realm creation ui

This commit is contained in:
Bill Burke 2013-08-03 12:00:29 -04:00
parent 8b00fff5ee
commit d4f8d2dc7a
112 changed files with 75793 additions and 174 deletions

View file

@ -10,6 +10,7 @@ import java.util.Set;
*/
public class RealmRepresentation {
protected String self; // link
protected String id;
protected String realm;
protected int tokenLifespan;
protected int accessCodeLifespan;
@ -34,6 +35,14 @@ public class RealmRepresentation {
this.self = self;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getRealm() {
return realm;
}

View file

@ -0,0 +1,314 @@
/* General styles */
@media (min-width: 1200px) {
#actions-bg {width: 1150px;}
#container-right-bg {
margin-left: 300px;
width: 900px;
}
.span9 {
width: 840px;
padding-left: 30px;
padding-right: 30px;
}
.initial {margin-left: 160px;}
.form-mobile-redirect .header-mobile-redirect .control-group,
.form-mobile-redirect .header-mobile-redirect .control-group:last-child {
width: 300px;
margin-left: 60px;
margin-bottom: 0;
}
.header-mobile-redirect input, .header-mobile-redirect select {width: 175px;}
tbody.sortable tr td:nth-child(1) {width: 150px;}
tbody.sortable tr td:nth-child(2) {width: 420px;}
tbody.sortable tr td:nth-child(3v) {width: 130px;}
#mappings .input-medium {width: 180px;}
footer {width: 1170px;}
footer p {margin-left: 300px;}
footer > ul {margin-right: 25px;}
}
@media (min-width: 1025px) {
td.actions > a,
td.actions > button,
td.actions > div {visibility: hidden}
tr:hover > td.actions > a,
tr:hover > td.actions > button,
tr:hover > td.actions > div {visibility: visible;}
}
@media (min-width: 768px) and (max-width: 979px) {
body {padding-top: 0;}
/* Topbar */
.navbar-fixed-top {
margin-bottom: 2px;
position: fixed;
}
.navbar-fixed-top .navbar-inner {padding: 0;}
.navbar .container {width: 724px;}
.navbar .brand {margin-left: -20px;}
.nav-collapse {
height: auto;
overflow: visible;
clear: none;
}
.nav-collapse .nav {margin-bottom: 0;}
.navbar .nav-collapse .nav.pull-right {float: right;}
.nav-collapse .nav > li {float: left;}
.nav-collapse .nav > li > a {
font-weight: normal;
padding: 9px 10px 11px;
margin-bottom: 0;
}
/* Topbar dropdown */
.navbar .dropdown-menu {display: none;}
.open .dropdown-menu,
.open .dropdown-menu:before,
.open .dropdown-menu:after {display: block;}
.open .dropdown-menu {
background-color: #FFFFFF;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 5px 5px 5px 5px;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
margin: 1px 0 0;
padding: 4px 0;
position: absolute;
}
.nav-collapse .dropdown-menu a {
color: #333333;
line-height: 18px;
padding: 3px 15px;
border-radius: 0;
font-weight: normal;
}
.nav-collapse .dropdown-menu li > a:hover,
.nav-collapse .dropdown-menu .active > a,
.nav-collapse .dropdown-menu .active > a:hover {
background-color: #0088CC;
color: #FFFFFF;
text-decoration: none;
}
/* Aside */
.nav-list a#add-page {top: 15px;}
#actions-bg {width: 730px;}
/* Content */
.form-horizontal .control-label {width: 125px;}
.form-horizontal .controls {margin-left: 140px;}
#container-right-bg {
margin-left: 186px;
width: 558px;
}
.span9 {
width: 518px;
padding-left: 20px;
padding-right: 20px;
}
.initial {margin-left: 0;}
.header-mobile-redirect .control-group label {
width: 100px;
text-align: right;
}
.form-mobile-redirect .header-mobile-redirect .control-group {width: 300px;}
.form-mobile-redirect .header-mobile-redirect .control-group:last-child {
margin-left: 87px;
margin-top: 10px;
}
#mappings .input-medium {width: 85px;}
#space-group .top-actions .pull-right {
float: none;
clear: both;
margin-top: 15px;
}
.window-tree {width: 356px;}
/* Footer */
footer {
width: 724px;
height: 50px;
margin-top: -50px;
}
footer p {
margin-left: 186px;
float: none;
}
footer > ul {
margin-left: 173px;
float: none;
margin-top: 5px;
}
}
@media (max-width: 767px) {
body {
padding: 0;
background: #fff;
}
.navbar-fixed-top, .navbar-fixed-bottom {
margin-left: 0;
margin-right: 0;
}
/* Topbar */
.navbar-fixed-top {
position: absolute;
margin-bottom: 0;
}
.navbar-fixed-top .navbar-inner {padding: 0;}
.nav-collapse {
height: auto;
overflow: visible;
clear: none;
}
.nav-collapse .nav {margin-bottom: 0;}
.navbar .nav-collapse .nav.pull-right {float: right;}
.navbar #settings {display: none;}
.nav-collapse .nav > li {float: left;}
.nav-collapse .nav > li > a {
font-weight: normal;
padding: 9px 10px 11px;
margin-bottom: 0;
}
/* Topbar dropdown */
.navbar .dropdown-menu {display: none;}
.open .dropdown-menu,
.open .dropdown-menu:before,
.open .dropdown-menu:after {display: block;}
.open .dropdown-menu {
background-color: #FFFFFF;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 5px 5px 5px 5px;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
margin: 1px 0 0;
padding: 4px 0;
position: absolute;
}
.nav-collapse .dropdown-menu a {
color: #333333;
line-height: 18px;
padding: 3px 15px;
border-radius: 0;
font-weight: normal;
}
.nav-collapse .dropdown-menu li > a:hover,
.nav-collapse .dropdown-menu .active > a,
.nav-collapse .dropdown-menu .active > a:hover {
background-color: #0088CC;
color: #FFFFFF;
text-decoration: none;
}
/* */
#wrapper {margin-top: 40px;}
aside.span3,
#actions-bg,
#container-right-bg {display: none;}
.row {
padding-left: 20px;
padding-right: 20px;
}
#container-right {
box-shadow: none;
background: none;
padding-bottom: 74px;
margin-top: 0;
}
.span9 {
width: 100%;
padding: 0;
}
.input-large,
.input-xlarge,
.input-xxlarge,
input[class*="span"],
select[class*="span"],
textarea[class*="span"],
.uneditable-input {width: 80%;}
footer {
width: auto;
}
footer > ul,
footer >p {
margin-left: 20px;
}
footer ul li:first-child {
padding-left: 0;
margin-left: 0;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,17 @@
.margin-top {
margin-top: 1em;
}
div#httpProviderError {
position: fixed;
left: 20px;
bottom: 20px;
}
div#loading {
color: #868686;
font-size: 14px;
position: fixed;
left: 0px;
bottom: 5px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 999 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 935 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View file

@ -0,0 +1,51 @@
<!doctype html>
<html lang="en" data-ng-app="keycloak">
<head>
<meta charset="utf-8">
<title>Keycloak</title>
<link href="lib/bootstrap/css/bootstrap.css" rel="stylesheet">
<link href="lib/bootstrap/css/bootstrap-responsive.css" rel="stylesheet">
<link href="css/admin.css" rel="stylesheet">
<link href="css/admin-responsive.css" rel="stylesheet">
<link href="css/styles.css" rel="stylesheet">
<script src="lib/jquery/jquery-1.10.2.js"></script>
<script src="lib/angular/angular.js"></script>
<script src="lib/angular/angular-resource.js"></script>
<script src="lib/angular/ui-bootstrap-tpls-0.4.0.js"></script>
<script src="/auth-server/rest/saas/isLoggedIn.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/loaders.js"></script>
<script src="js/services.js"></script>
</head>
<body data-ng-controller="GlobalCtrl">
<div class="alert-container" data-ng-show="notification" data-ng-click="notification = null">
<div class="alert alert-{{notification.type}}">{{notification.message}}</div>
</div>
<div id="wrap">
<div data-ng-include data-src="'partials/menu.html'"></div>
<div data-ng-view id="view" data-ng-hide="httpProviderError"></div>
<div id="httpProviderError" data-ng-show="httpProviderError">
<button class="btn btn-danger" data-ng-click="httpProviderError=null">
<strong>Error</strong> {{httpProviderError}}
</button>
</div>
<div id="loading">
<i class="icon-spinner icon-spin"></i> Loading...
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,290 @@
'use strict';
var module = angular.module('keycloak', [ 'keycloak.services', 'keycloak.loaders', 'keycloak.controllers', 'ui.bootstrap' ]);
var resourceRequests = 0;
module.config([ '$routeProvider', function($routeProvider) {
$routeProvider.when('/create/application', {
templateUrl : 'partials/application-detail.html',
resolve : {
application : function(ApplicationLoader) {
return {};
},
realms : function(RealmListLoader) {
return RealmListLoader();
}
},
controller : 'ApplicationDetailCtrl'
}).when('/applications/:application', {
templateUrl : 'partials/application-detail.html',
resolve : {
application : function(ApplicationLoader) {
return ApplicationLoader();
},
realms : function(RealmListLoader) {
return RealmListLoader();
}
},
controller : 'ApplicationDetailCtrl'
}).when('/applications', {
templateUrl : 'partials/application-list.html',
resolve : {
applications : function(ApplicationListLoader) {
return ApplicationListLoader();
}
},
controller : 'ApplicationListCtrl'
})
.when('/create/realm', {
templateUrl : 'partials/realm-detail.html',
resolve : {
realm : function(RealmLoader) {
return {};
}
},
controller : 'RealmDetailCtrl'
}).when('/realms/:realm', {
templateUrl : 'partials/realm-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
}
},
controller : 'RealmDetailCtrl'
}).when('/realms', {
templateUrl : 'partials/realm-list.html',
controller : 'RealmListCtrl'
})
.when('/create/user/:realm', {
templateUrl : 'partials/user-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
user : function() {
return {};
}
},
controller : 'UserDetailCtrl'
}).when('/realms/:realm/users/:user', {
templateUrl : 'partials/user-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
user : function(UserLoader) {
return UserLoader();
}
},
controller : 'UserDetailCtrl'
}).when('/realms/:realm/users', {
templateUrl : 'partials/user-list.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
users : function(UserListLoader) {
return UserListLoader();
}
},
controller : 'UserListCtrl'
})
.when('/realms/:realm/roles', {
templateUrl : 'partials/role-mapping.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function() {
return null;
},
users : function() {
return null;
},
role : function() {
return null;
}
},
controller : 'RoleMappingCtrl'
}).when('/realms/:realm/roles/:role', {
templateUrl : 'partials/role-mapping.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function() {
return null;
},
role : function($route) {
return $route.current.params.role;
},
users : function(RoleMappingLoader) {
return RoleMappingLoader();
}
},
controller : 'RoleMappingCtrl'
})
.when('/applications/:application/roles', {
templateUrl : 'partials/role-mapping.html',
resolve : {
realm : function(ApplicationLoader) {
return ApplicationLoader();
},
users : function() {
return null;
},
role : function() {
return null;
}
},
controller : 'RoleMappingCtrl'
}).when('/applications/:application/roles/:role', {
templateUrl : 'partials/role-mapping.html',
resolve : {
realm : function(ApplicationLoader) {
return ApplicationLoader();
},
role : function($route) {
return $route.current.params.role;
},
users : function(RoleMappingLoader) {
return RoleMappingLoader();
}
},
controller : 'RoleMappingCtrl'
})
.otherwise({
templateUrl : 'partials/home.html'
});
} ]);
module.config(function($httpProvider) {
$httpProvider.responseInterceptors.push('errorInterceptor');
var spinnerFunction = function(data, headersGetter) {
if (resourceRequests == 0) {
$('#loading').show();
}
resourceRequests++;
return data;
};
$httpProvider.defaults.transformRequest.push(spinnerFunction);
$httpProvider.responseInterceptors.push('spinnerInterceptor');
});
module.factory('errorInterceptor', function($q, $window, $rootScope, $location) {
return function(promise) {
return promise.then(function(response) {
$rootScope.httpProviderError = null;
return response;
}, function(response) {
$rootScope.httpProviderError = response.status;
return $q.reject(response);
});
};
});
module.factory('spinnerInterceptor', function($q, $window, $rootScope, $location) {
return function(promise) {
return promise.then(function(response) {
resourceRequests--;
if (resourceRequests == 0) {
$('#loading').hide();
}
return response;
}, function(response) {
resourceRequests--;
if (resourceRequests == 0) {
$('#loading').hide();
}
return $q.reject(response);
});
};
});
module.directive('kcInput', function() {
var d = {
scope : true,
replace : false,
link : function(scope, element, attrs) {
var form = element.closest('form');
var label = element.children('label');
var input = element.children('input');
var id = form.attr('name') + '.' + input.attr('name');
element.attr('class', 'control-group');
label.attr('class', 'control-label');
label.attr('for', id);
input.wrap('<div class="controls"/>');
input.attr('id', id);
if (!input.attr('placeHolder')) {
input.attr('placeHolder', label.text());
}
if (input.attr('required')) {
label.append(' <span class="required">*</span>');
}
}
};
return d;
});
module.directive('kcEnter', function() {
return function(scope, element, attrs) {
element.bind("keydown keypress", function(event) {
if (event.which === 13) {
scope.$apply(function() {
scope.$eval(attrs.kcEnter);
});
event.preventDefault();
}
});
};
});
module.filter('remove', function() {
return function(input, remove, attribute) {
if (!input || !remove) {
return input;
}
var out = [];
for ( var i = 0; i < input.length; i++) {
var e = input[i];
for (var j = 0; j < remove.length; j++) {
if (attribute) {
if (remove[j][attribute] == e[attribute]) {
e = null;
break;
}
} else {
if (remove[j] == e) {
e = null;
break;
}
}
}
if (e != null) {
out.push(e);
}
}
return out;
};
});

View file

@ -0,0 +1,373 @@
'use strict';
var module = angular.module('keycloak.controllers', [ 'keycloak.services' ]);
module.controller('GlobalCtrl', function($scope, Auth, $location, Notifications) {
$scope.addMessage = function() {
Notifications.success("test");
};
$scope.auth = Auth;
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
});
module.controller('ApplicationListCtrl', function($scope, Application) {
$scope.applications = Application.query();
});
module.controller('ApplicationDetailCtrl', function($scope, application, Application, realms, $location, $window, Dialog,
Notifications) {
$scope.application = angular.copy(application);
$scope.realms = realms;
$scope.create = !application.id;
$scope.changed = $scope.create;
$scope.$watch('application', function() {
if (!angular.equals($scope.application, application)) {
$scope.changed = true;
}
}, true);
$scope.addRole = function() {
if ($scope.newRole) {
if ($scope.application.roles) {
for ( var i = 0; i < $scope.application.roles.length; i++) {
if ($scope.application.roles[i] == $scope.newRole) {
Notifications.warn("Role already exists");
$scope.newRole = null;
return;
}
}
}
if (!$scope.application.roles) {
$scope.application.roles = [];
}
$scope.application.roles.push($scope.newRole);
$scope.newRole = null;
}
}
$scope.removeRole = function(role) {
Dialog.confirmDelete(role, 'role', function() {
var i = $scope.application.roles.indexOf(role);
if (i > -1) {
$scope.application.roles.splice(i, 1);
}
if ($scope.application.initialRoles) {
$scope.removeInitialRole(role);
}
});
};
$scope.addInitialRole = function() {
if ($scope.newInitialRole) {
if (!$scope.application.initialRoles) {
$scope.application.initialRoles = [];
}
$scope.application.initialRoles.push($scope.newInitialRole);
$scope.newInitialRole = null;
}
}
$scope.removeInitialRole = function(role) {
var i = $scope.application.initialRoles.indexOf(role);
if (i > -1) {
$scope.application.initialRoles.splice(i, 1);
}
};
$scope.save = function() {
if ($scope.applicationForm.$valid) {
if ($scope.create) {
Application.save($scope.application, function(data, headers) {
var l = headers().location;
var id = l.substring(l.lastIndexOf("/") + 1);
$location.url("/applications/" + id);
Notifications.success("Created application");
});
} else {
Application.update($scope.application, function() {
$scope.changed = false;
application = angular.copy($scope.application);
Notifications.success("Saved changes to the application");
});
}
} else {
$scope.applicationForm.showErrors = true;
}
};
$scope.reset = function() {
$scope.application = angular.copy(application);
$scope.changed = false;
$scope.applicationForm.showErrors = false;
};
$scope.cancel = function() {
$location.url("/applications");
};
$scope.remove = function() {
Dialog.confirmDelete($scope.application.name, 'application', function() {
$scope.application.$remove(function() {
$location.url("/applications");
Notifications.success("Deleted application");
});
});
};
});
module.controller('RealmListCtrl', function($scope, Realm) {
$scope.realms = Realm.get();
});
module.controller('RealmDetailCtrl', function($scope, Realm, realm, $location, Dialog, Notifications) {
$scope.realm = angular.copy(realm);
$scope.create = !realm.id;
if ($scope.create) {
$scope.realm.enabled = true;
$scope.realm.requireSsl = true;
$scope.realm.cookieLoginAllowed = true;
$scope.realm.tokenLifespan = 300;
$scope.realm.tokenLifespanUnit = 'SECONDS';
$scope.realm.accessCodeLifespan = 300;
$scope.realm.accessCodeLifespanUnit = 'SECONDS';
} else {
$scope.realm.name = realm.realm;
$scope.realm.requireSsl = !$scope.realm.sslNotRequired;
$scope.realm.tokenLifespanUnit = 'SECONDS';
$scope.realm.acessCodeLifespanUnit = 'SECONDS';
}
$scope.changed = $scope.create;
$scope.$watch('realm', function() {
if (!angular.equals($scope.realm, realm)) {
$scope.changed = true;
}
}, true);
$scope.addRole = function() {
if ($scope.newRole) {
if ($scope.realm.roles) {
for ( var i = 0; i < $scope.realm.roles.length; i++) {
if ($scope.realm.roles[i] == $scope.newRole) {
Notifications.warn("Role already exists");
$scope.newRole = null;
return;
}
}
}
if (!$scope.realm.roles) {
$scope.realm.roles = [];
}
$scope.realm.roles.push($scope.newRole);
$scope.newRole = null;
}
}
$scope.removeRole = function(role) {
Dialog.confirmDelete(role, 'role', function() {
var i = $scope.realm.roles.indexOf(role);
if (i > -1) {
$scope.realm.roles.splice(i, 1);
}
if ($scope.realm.initialRoles) {
$scope.removeInitialRole(role);
}
});
};
$scope.addInitialRole = function() {
if ($scope.newInitialRole) {
if (!$scope.realm.initialRoles) {
$scope.realm.initialRoles = [];
}
$scope.realm.initialRoles.push($scope.newInitialRole);
$scope.newInitialRole = null;
}
}
$scope.removeInitialRole = function(role) {
var i = $scope.realm.initialRoles.indexOf(role);
if (i > -1) {
$scope.realm.initialRoles.splice(i, 1);
}
};
$scope.save = function() {
if ($scope.realmForm.$valid) {
var realmCopy = {
realm: $scope.realm.name,
enabled: $scope.realm.enabled,
cookieLoginAllowed: $scope.realm.cookieLoginAllowed,
sslNotRequired: !$scope.realm.requireSsl,
tokenLifespan: $scope.realm.tokenLifespan,
accessCodeLifespan: $scope.realm.accessCodeLifespan
};
if ($scope.create) {
Realm.save(realmCopy, function(data, headers) {
var l = headers().location;
var id = l.substring(l.lastIndexOf("/") + 1);
$location.url("/realms/" + id);
Notifications.success("Created realm");
});
} else {
Realm.update(realmCopy, function() {
$scope.changed = false;
realm = angular.copy($scope.realm);
Notifications.success("Saved changes to realm");
});
}
} else {
$scope.realmForm.showErrors = true;
}
};
$scope.reset = function() {
$scope.realm = angular.copy(realm);
$scope.changed = false;
$scope.realmForm.showErrors = false;
};
$scope.cancel = function() {
$location.url("/realms");
};
$scope.remove = function() {
Dialog.confirmDelete($scope.realm.name, 'realm', function() {
Realm.remove($scope.realm, function() {
$location.url("/realms");
Notifications.success("Deleted realm");
});
});
};
});
module.controller('UserListCtrl', function($scope, realm, users) {
$scope.realm = realm;
$scope.users = users;
});
module.controller('UserDetailCtrl', function($scope, realm, user, User, $location, Dialog, Notifications) {
$scope.realm = realm;
$scope.user = angular.copy(user);
$scope.create = !user.userId;
$scope.changed = $scope.create;
$scope.$watch('user', function() {
if (!angular.equals($scope.user, user)) {
$scope.changed = true;
}
}, true);
$scope.save = function() {
if ($scope.userForm.$valid) {
User.save({
realm : realm.id
}, $scope.user, function() {
$scope.changed = false;
user = angular.copy($scope.user);
if ($scope.create) {
$location.url("/realms/" + realm.id + "/users/" + $scope.user.userId);
Notifications.success("Created user");
} else {
Notifications.success("Saved changes to user");
}
});
} else {
$scope.userForm.showErrors = true;
}
};
$scope.reset = function() {
$scope.user = angular.copy(user);
$scope.changed = false;
$scope.userForm.showErrors = false;
};
$scope.cancel = function() {
$location.url("/realms/" + realm.id + "/users");
};
$scope.remove = function() {
Dialog.confirmDelete($scope.user.userId, 'user', function() {
$scope.user.$remove({
realm : realm.id,
userId : $scope.user.userId
}, function() {
$location.url("/realms/" + realm.id + "/users");
Notifications.success("Deleted user");
});
});
};
});
module.controller('RoleMappingCtrl', function($scope, realm, User, users, role, RoleMapping, Notifications) {
$scope.realm = realm;
$scope.realmId = realm.realm || realm.id;
$scope.allUsers = User.query({ realm : $scope.realmId });
$scope.users = users;
$scope.role = role;
$scope.addUser = function() {
var user = $scope.newUser;
$scope.newUser = null;
for ( var i = 0; i < $scope.allUsers.length; i++) {
if ($scope.allUsers[i].userId == user) {
user = $scope.allUsers[i];
RoleMapping.save({
realm : $scope.realmId,
role : role
}, user, function() {
$scope.users = RoleMapping.query({
realm : $scope.realmId,
role : role
});
Notifications.success("Added role mapping for user");
});
}
}
}
$scope.removeUser = function(userId) {
for (var i = 0; i < $scope.users.length; i++) {
var user = $scope.users[i];
if ($scope.users[i].userId == userId) {
RoleMapping.delete({
realm : $scope.realmId,
role : role
}, user, function() {
$scope.users = RoleMapping.query({
realm : $scope.realmId,
role : role
});
Notifications.success("Removed role mapping for user");
});
}
}
}
});

View file

@ -0,0 +1,84 @@
'use strict';
var module = angular.module('keycloak.loaders', [ 'keycloak.services', 'ngResource' ]);
module.factory('Loader', function($q) {
var loader = {};
loader.get = function(service, id) {
return function() {
var i = id && id();
var delay = $q.defer();
service.get(i, function(entry) {
delay.resolve(entry);
}, function() {
delay.reject('Unable to fetch ' + i);
});
return delay.promise;
};
}
loader.query = function(service, id) {
return function() {
var i = id && id();
var delay = $q.defer();
service.query(i, function(entry) {
delay.resolve(entry);
}, function() {
delay.reject('Unable to fetch ' + i);
});
return delay.promise;
};
}
return loader;
});
module.factory('ApplicationListLoader', function(Loader, Application, $q) {
return Loader.query(Application);
});
module.factory('ApplicationLoader', function(Loader, Application, $route, $q) {
return Loader.get(Application, function() {
return {
id : $route.current.params.application
}
});
});
module.factory('RealmListLoader', function(Loader, Realm, $q) {
return Loader.get(Realm);
});
module.factory('RealmLoader', function(Loader, Realm, $route, $q) {
return Loader.get(Realm, function() {
return {
id : $route.current.params.realm
}
});
});
module.factory('UserListLoader', function(Loader, User, $route, $q) {
return Loader.query(User, function() {
return {
realm : $route.current.params.realm
}
});
});
module.factory('UserLoader', function(Loader, User, $route, $q) {
return Loader.get(User, function() {
return {
realm : $route.current.params.realm,
userId : $route.current.params.user
}
});
});
module.factory('RoleMappingLoader', function(Loader, RoleMapping, $route, $q) {
var realm = $route.current.params.realm || $route.current.params.application;
return Loader.query(RoleMapping, function() {
return {
realm : realm,
role : $route.current.params.role
}
});
});

View file

@ -0,0 +1,149 @@
'use strict';
var module = angular.module('keycloak.services', [ 'ngResource' ]);
module.service('Auth', function($resource, $http, $location, $routeParams) {
var auth = {
loggedIn : keycloakCookieLoggedIn
};
auth.user = {
userId : null,
displayName : null
};
auth.logout = function() {
auth.user = {
userId : null,
displayName : null
};
auth.loggedIn = false;
$http.get('/auth-server/rest/saas/logout-cookie');
};
if (!auth.loggedIn) {
return auth;
}
$http.get('/auth-server/rest/saas/whoami').success(function(data, status) {
auth.user = data;
//alert(data.userId);
})
.error(function(data, status) {
alert("Failed!");
});
return auth;
});
module.service('Dialog', function($dialog) {
var dialog = {};
dialog.confirmDelete = function(name, type, success) {
var title = 'Delete ' + name;
var msg = 'Are you sure you want to permanently delete this ' + type + '?';
var btns = [ {
result : 'cancel',
label : 'Cancel'
}, {
result : 'ok',
label : 'Delete this ' + type,
cssClass : 'btn-primary'
} ];
$dialog.messageBox(title, msg, btns).open().then(function(result) {
if (result == "ok") {
success();
}
});
}
return dialog
});
module.factory('Notifications', function($rootScope, $timeout) {
var notifications = {};
var scheduled = null;
var schedulePop = function() {
if (scheduled) {
$timeout.cancel(scheduled);
}
scheduled = $timeout(function() {
$rootScope.notification = null;
scheduled = null;
}, 3000);
};
if (!$rootScope.notifications) {
$rootScope.notifications = [];
}
notifications.message = function(type, message) {
$rootScope.notification = {
type : type,
message : message
};
schedulePop();
}
notifications.info = function(message) {
notifications.message("info", message);
};
notifications.success = function(message) {
notifications.message("success", message);
};
notifications.error = function(message) {
notifications.message("error", message);
};
notifications.warn = function(message) {
notifications.message("warn", message);
};
return notifications;
});
module.factory('Application', function($resource) {
return $resource('/keycloak-server/ui/api/applications/:id', {
id : '@id'
}, {
update : {
method : 'PUT'
}
});
});
module.factory('Provider', function($resource) {
return $resource('/ejs-identity/api/admin/providers');
});
module.factory('Realm', function($resource) {
return $resource('/auth-server/rest/saas/admin/realms/:id', {
id : '@id'
}, {
update : {
method : 'PUT'
}
});
});
module.factory('RoleMapping', function($resource) {
return $resource('/keycloak-server/ui/api/roles/:realm/:role/:userId', {
realm : '@realm',
role : '@role',
userId : '@userId'
}, {
save : {
method : 'PUT'
}
});
});
module.factory('User', function($resource) {
return $resource('/keycloak-server/ui/api/realms/:realm/users/:userId', {
realm : '@realm',
userId : '@userId'
}, {
save : {
method : 'PUT'
}
});
});

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,175 @@
/**
* @license AngularJS v1.0.7
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
(function(window, angular, undefined) {
'use strict';
var directive = {};
directive.dropdownToggle =
['$document', '$location', '$window',
function ($document, $location, $window) {
var openElement = null, close;
return {
restrict: 'C',
link: function(scope, element, attrs) {
scope.$watch(function dropdownTogglePathWatch(){return $location.path();}, function dropdownTogglePathWatchAction() {
close && close();
});
element.parent().bind('click', function(event) {
close && close();
});
element.bind('click', function(event) {
event.preventDefault();
event.stopPropagation();
var iWasOpen = false;
if (openElement) {
iWasOpen = openElement === element;
close();
}
if (!iWasOpen){
element.parent().addClass('open');
openElement = element;
close = function (event) {
event && event.preventDefault();
event && event.stopPropagation();
$document.unbind('click', close);
element.parent().removeClass('open');
close = null;
openElement = null;
}
$document.bind('click', close);
}
});
}
};
}];
directive.tabbable = function() {
return {
restrict: 'C',
compile: function(element) {
var navTabs = angular.element('<ul class="nav nav-tabs"></ul>'),
tabContent = angular.element('<div class="tab-content"></div>');
tabContent.append(element.contents());
element.append(navTabs).append(tabContent);
},
controller: ['$scope', '$element', function($scope, $element) {
var navTabs = $element.contents().eq(0),
ngModel = $element.controller('ngModel') || {},
tabs = [],
selectedTab;
ngModel.$render = function() {
var $viewValue = this.$viewValue;
if (selectedTab ? (selectedTab.value != $viewValue) : $viewValue) {
if(selectedTab) {
selectedTab.paneElement.removeClass('active');
selectedTab.tabElement.removeClass('active');
selectedTab = null;
}
if($viewValue) {
for(var i = 0, ii = tabs.length; i < ii; i++) {
if ($viewValue == tabs[i].value) {
selectedTab = tabs[i];
break;
}
}
if (selectedTab) {
selectedTab.paneElement.addClass('active');
selectedTab.tabElement.addClass('active');
}
}
}
};
this.addPane = function(element, attr) {
var li = angular.element('<li><a href></a></li>'),
a = li.find('a'),
tab = {
paneElement: element,
paneAttrs: attr,
tabElement: li
};
tabs.push(tab);
attr.$observe('value', update)();
attr.$observe('title', function(){ update(); a.text(tab.title); })();
function update() {
tab.title = attr.title;
tab.value = attr.value || attr.title;
if (!ngModel.$setViewValue && (!ngModel.$viewValue || tab == selectedTab)) {
// we are not part of angular
ngModel.$viewValue = tab.value;
}
ngModel.$render();
}
navTabs.append(li);
li.bind('click', function(event) {
event.preventDefault();
event.stopPropagation();
if (ngModel.$setViewValue) {
$scope.$apply(function() {
ngModel.$setViewValue(tab.value);
ngModel.$render();
});
} else {
// we are not part of angular
ngModel.$viewValue = tab.value;
ngModel.$render();
}
});
return function() {
tab.tabElement.remove();
for(var i = 0, ii = tabs.length; i < ii; i++ ) {
if (tab == tabs[i]) {
tabs.splice(i, 1);
}
}
};
}
}]
};
};
directive.table = function() {
return {
restrict: 'E',
link: function(scope, element, attrs) {
element[0].className = 'table table-bordered table-striped code-table';
}
};
};
directive.tabPane = function() {
return {
require: '^tabbable',
restrict: 'C',
link: function(scope, element, attrs, tabsCtrl) {
element.bind('$remove', tabsCtrl.addPane(element, attrs));
}
};
};
angular.module('bootstrap', []).directive(directive);
})(window, window.angular);

View file

@ -0,0 +1,185 @@
/**
* @license AngularJS v1.0.7
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
(function(window, angular, undefined) {
'use strict';
/**
* @ngdoc overview
* @name ngCookies
*/
angular.module('ngCookies', ['ng']).
/**
* @ngdoc object
* @name ngCookies.$cookies
* @requires $browser
*
* @description
* Provides read/write access to browser's cookies.
*
* Only a simple Object is exposed and by adding or removing properties to/from
* this object, new cookies are created/deleted at the end of current $eval.
*
* @example
<doc:example>
<doc:source>
<script>
function ExampleController($cookies) {
// Retrieving a cookie
var favoriteCookie = $cookies.myFavorite;
// Setting a cookie
$cookies.myFavorite = 'oatmeal';
}
</script>
</doc:source>
</doc:example>
*/
factory('$cookies', ['$rootScope', '$browser', function ($rootScope, $browser) {
var cookies = {},
lastCookies = {},
lastBrowserCookies,
runEval = false,
copy = angular.copy,
isUndefined = angular.isUndefined;
//creates a poller fn that copies all cookies from the $browser to service & inits the service
$browser.addPollFn(function() {
var currentCookies = $browser.cookies();
if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl
lastBrowserCookies = currentCookies;
copy(currentCookies, lastCookies);
copy(currentCookies, cookies);
if (runEval) $rootScope.$apply();
}
})();
runEval = true;
//at the end of each eval, push cookies
//TODO: this should happen before the "delayed" watches fire, because if some cookies are not
// strings or browser refuses to store some cookies, we update the model in the push fn.
$rootScope.$watch(push);
return cookies;
/**
* Pushes all the cookies from the service to the browser and verifies if all cookies were stored.
*/
function push() {
var name,
value,
browserCookies,
updated;
//delete any cookies deleted in $cookies
for (name in lastCookies) {
if (isUndefined(cookies[name])) {
$browser.cookies(name, undefined);
}
}
//update all cookies updated in $cookies
for(name in cookies) {
value = cookies[name];
if (!angular.isString(value)) {
if (angular.isDefined(lastCookies[name])) {
cookies[name] = lastCookies[name];
} else {
delete cookies[name];
}
} else if (value !== lastCookies[name]) {
$browser.cookies(name, value);
updated = true;
}
}
//verify what was actually stored
if (updated){
updated = false;
browserCookies = $browser.cookies();
for (name in cookies) {
if (cookies[name] !== browserCookies[name]) {
//delete or reset all cookies that the browser dropped from $cookies
if (isUndefined(browserCookies[name])) {
delete cookies[name];
} else {
cookies[name] = browserCookies[name];
}
updated = true;
}
}
}
}
}]).
/**
* @ngdoc object
* @name ngCookies.$cookieStore
* @requires $cookies
*
* @description
* Provides a key-value (string-object) storage, that is backed by session cookies.
* Objects put or retrieved from this storage are automatically serialized or
* deserialized by angular's toJson/fromJson.
* @example
*/
factory('$cookieStore', ['$cookies', function($cookies) {
return {
/**
* @ngdoc method
* @name ngCookies.$cookieStore#get
* @methodOf ngCookies.$cookieStore
*
* @description
* Returns the value of given cookie key
*
* @param {string} key Id to use for lookup.
* @returns {Object} Deserialized cookie value.
*/
get: function(key) {
var value = $cookies[key];
return value ? angular.fromJson(value) : value;
},
/**
* @ngdoc method
* @name ngCookies.$cookieStore#put
* @methodOf ngCookies.$cookieStore
*
* @description
* Sets a value for given cookie key
*
* @param {string} key Id for the `value`.
* @param {Object} value Value to be stored.
*/
put: function(key, value) {
$cookies[key] = angular.toJson(value);
},
/**
* @ngdoc method
* @name ngCookies.$cookieStore#remove
* @methodOf ngCookies.$cookieStore
*
* @description
* Remove given cookie
*
* @param {string} key Id of the key-value pair to delete.
*/
remove: function(key) {
delete $cookies[key];
}
};
}]);
})(window, window.angular);

View file

@ -0,0 +1,277 @@
/**
* @license AngularJS v1.0.7
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
(
/**
* @ngdoc interface
* @name angular.Module
* @description
*
* Interface for configuring angular {@link angular.module modules}.
*/
function setupModuleLoader(window) {
function ensure(obj, name, factory) {
return obj[name] || (obj[name] = factory());
}
return ensure(ensure(window, 'angular', Object), 'module', function() {
/** @type {Object.<string, angular.Module>} */
var modules = {};
/**
* @ngdoc function
* @name angular.module
* @description
*
* The `angular.module` is a global place for creating and registering Angular modules. All
* modules (angular core or 3rd party) that should be available to an application must be
* registered using this mechanism.
*
*
* # Module
*
* A module is a collocation of services, directives, filters, and configuration information. Module
* is used to configure the {@link AUTO.$injector $injector}.
*
* <pre>
* // Create a new module
* var myModule = angular.module('myModule', []);
*
* // register a new service
* myModule.value('appName', 'MyCoolApp');
*
* // configure existing services inside initialization blocks.
* myModule.config(function($locationProvider) {
'use strict';
* // Configure existing providers
* $locationProvider.hashPrefix('!');
* });
* </pre>
*
* Then you can create an injector and load your modules like this:
*
* <pre>
* var injector = angular.injector(['ng', 'MyModule'])
* </pre>
*
* However it's more likely that you'll just use
* {@link ng.directive:ngApp ngApp} or
* {@link angular.bootstrap} to simplify this process for you.
*
* @param {!string} name The name of the module to create or retrieve.
* @param {Array.<string>=} requires If specified then new module is being created. If unspecified then the
* the module is being retrieved for further configuration.
* @param {Function} configFn Optional configuration function for the module. Same as
* {@link angular.Module#config Module#config()}.
* @returns {module} new module with the {@link angular.Module} api.
*/
return function module(name, requires, configFn) {
if (requires && modules.hasOwnProperty(name)) {
modules[name] = null;
}
return ensure(modules, name, function() {
if (!requires) {
throw Error('No module: ' + name);
}
/** @type {!Array.<Array.<*>>} */
var invokeQueue = [];
/** @type {!Array.<Function>} */
var runBlocks = [];
var config = invokeLater('$injector', 'invoke');
/** @type {angular.Module} */
var moduleInstance = {
// Private state
_invokeQueue: invokeQueue,
_runBlocks: runBlocks,
/**
* @ngdoc property
* @name angular.Module#requires
* @propertyOf angular.Module
* @returns {Array.<string>} List of module names which must be loaded before this module.
* @description
* Holds the list of modules which the injector will load before the current module is loaded.
*/
requires: requires,
/**
* @ngdoc property
* @name angular.Module#name
* @propertyOf angular.Module
* @returns {string} Name of the module.
* @description
*/
name: name,
/**
* @ngdoc method
* @name angular.Module#provider
* @methodOf angular.Module
* @param {string} name service name
* @param {Function} providerType Construction function for creating new instance of the service.
* @description
* See {@link AUTO.$provide#provider $provide.provider()}.
*/
provider: invokeLater('$provide', 'provider'),
/**
* @ngdoc method
* @name angular.Module#factory
* @methodOf angular.Module
* @param {string} name service name
* @param {Function} providerFunction Function for creating new instance of the service.
* @description
* See {@link AUTO.$provide#factory $provide.factory()}.
*/
factory: invokeLater('$provide', 'factory'),
/**
* @ngdoc method
* @name angular.Module#service
* @methodOf angular.Module
* @param {string} name service name
* @param {Function} constructor A constructor function that will be instantiated.
* @description
* See {@link AUTO.$provide#service $provide.service()}.
*/
service: invokeLater('$provide', 'service'),
/**
* @ngdoc method
* @name angular.Module#value
* @methodOf angular.Module
* @param {string} name service name
* @param {*} object Service instance object.
* @description
* See {@link AUTO.$provide#value $provide.value()}.
*/
value: invokeLater('$provide', 'value'),
/**
* @ngdoc method
* @name angular.Module#constant
* @methodOf angular.Module
* @param {string} name constant name
* @param {*} object Constant value.
* @description
* Because the constant are fixed, they get applied before other provide methods.
* See {@link AUTO.$provide#constant $provide.constant()}.
*/
constant: invokeLater('$provide', 'constant', 'unshift'),
/**
* @ngdoc method
* @name angular.Module#filter
* @methodOf angular.Module
* @param {string} name Filter name.
* @param {Function} filterFactory Factory function for creating new instance of filter.
* @description
* See {@link ng.$filterProvider#register $filterProvider.register()}.
*/
filter: invokeLater('$filterProvider', 'register'),
/**
* @ngdoc method
* @name angular.Module#controller
* @methodOf angular.Module
* @param {string} name Controller name.
* @param {Function} constructor Controller constructor function.
* @description
* See {@link ng.$controllerProvider#register $controllerProvider.register()}.
*/
controller: invokeLater('$controllerProvider', 'register'),
/**
* @ngdoc method
* @name angular.Module#directive
* @methodOf angular.Module
* @param {string} name directive name
* @param {Function} directiveFactory Factory function for creating new instance of
* directives.
* @description
* See {@link ng.$compileProvider#directive $compileProvider.directive()}.
*/
directive: invokeLater('$compileProvider', 'directive'),
/**
* @ngdoc method
* @name angular.Module#config
* @methodOf angular.Module
* @param {Function} configFn Execute this function on module load. Useful for service
* configuration.
* @description
* Use this method to register work which needs to be performed on module loading.
*/
config: config,
/**
* @ngdoc method
* @name angular.Module#run
* @methodOf angular.Module
* @param {Function} initializationFn Execute this function after injector creation.
* Useful for application initialization.
* @description
* Use this method to register work which should be performed when the injector is done
* loading all modules.
*/
run: function(block) {
runBlocks.push(block);
return this;
}
};
if (configFn) {
config(configFn);
}
return moduleInstance;
/**
* @param {string} provider
* @param {string} method
* @param {String=} insertMethod
* @returns {angular.Module}
*/
function invokeLater(provider, method, insertMethod) {
return function() {
invokeQueue[insertMethod || 'push']([provider, method, arguments]);
return moduleInstance;
}
}
});
};
});
}
)(window);
/**
* Closure compiler type information
*
* @typedef { {
* requires: !Array.<string>,
* invokeQueue: !Array.<Array.<*>>,
*
* service: function(string, Function):angular.Module,
* factory: function(string, Function):angular.Module,
* value: function(string, *):angular.Module,
*
* filter: function(string, Function):angular.Module,
*
* init: function(Function):angular.Module
* } }
*/
angular.Module;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,457 @@
/**
* @license AngularJS v1.0.7
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
(function(window, angular, undefined) {
'use strict';
/**
* @ngdoc overview
* @name ngResource
* @description
*/
/**
* @ngdoc object
* @name ngResource.$resource
* @requires $http
*
* @description
* A factory which creates a resource object that lets you interact with
* [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources.
*
* The returned resource object has action methods which provide high-level behaviors without
* the need to interact with the low level {@link ng.$http $http} service.
*
* # Installation
* To use $resource make sure you have included the `angular-resource.js` that comes in Angular
* package. You can also find this file on Google CDN, bower as well as at
* {@link http://code.angularjs.org/ code.angularjs.org}.
*
* Finally load the module in your application:
*
* angular.module('app', ['ngResource']);
*
* and you are ready to get started!
*
* @param {string} url A parameterized URL template with parameters prefixed by `:` as in
* `/user/:username`. If you are using a URL with a port number (e.g.
* `http://example.com:8080/api`), you'll need to escape the colon character before the port
* number, like this: `$resource('http://example.com\\:8080/api')`.
*
* @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
* `actions` methods.
*
* Each key value in the parameter object is first bound to url template if present and then any
* excess keys are appended to the url search query after the `?`.
*
* Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in
* URL `/path/greet?salutation=Hello`.
*
* If the parameter value is prefixed with `@` then the value of that parameter is extracted from
* the data object (useful for non-GET operations).
*
* @param {Object.<Object>=} actions Hash with declaration of custom action that should extend the
* default set of resource actions. The declaration should be created in the following format:
*
* {action1: {method:?, params:?, isArray:?},
* action2: {method:?, params:?, isArray:?},
* ...}
*
* Where:
*
* - `action` {string} The name of action. This name becomes the name of the method on your
* resource object.
* - `method` {string} HTTP request method. Valid methods are: `GET`, `POST`, `PUT`, `DELETE`,
* and `JSONP`
* - `params` {object=} Optional set of pre-bound parameters for this action.
* - isArray {boolean=} If true then the returned object for this action is an array, see
* `returns` section.
*
* @returns {Object} A resource "class" object with methods for the default set of resource actions
* optionally extended with custom `actions`. The default set contains these actions:
*
* { 'get': {method:'GET'},
* 'save': {method:'POST'},
* 'query': {method:'GET', isArray:true},
* 'remove': {method:'DELETE'},
* 'delete': {method:'DELETE'} };
*
* Calling these methods invoke an {@link ng.$http} with the specified http method,
* destination and parameters. When the data is returned from the server then the object is an
* instance of the resource class. The actions `save`, `remove` and `delete` are available on it
* as methods with the `$` prefix. This allows you to easily perform CRUD operations (create,
* read, update, delete) on server-side data like this:
* <pre>
var User = $resource('/user/:userId', {userId:'@id'});
var user = User.get({userId:123}, function() {
user.abc = true;
user.$save();
});
</pre>
*
* It is important to realize that invoking a $resource object method immediately returns an
* empty reference (object or array depending on `isArray`). Once the data is returned from the
* server the existing reference is populated with the actual data. This is a useful trick since
* usually the resource is assigned to a model which is then rendered by the view. Having an empty
* object results in no rendering, once the data arrives from the server then the object is
* populated with the data and the view automatically re-renders itself showing the new data. This
* means that in most case one never has to write a callback function for the action methods.
*
* The action methods on the class object or instance object can be invoked with the following
* parameters:
*
* - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])`
* - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])`
* - non-GET instance actions: `instance.$action([parameters], [success], [error])`
*
*
* @example
*
* # Credit card resource
*
* <pre>
// Define CreditCard class
var CreditCard = $resource('/user/:userId/card/:cardId',
{userId:123, cardId:'@id'}, {
charge: {method:'POST', params:{charge:true}}
});
// We can retrieve a collection from the server
var cards = CreditCard.query(function() {
// GET: /user/123/card
// server returns: [ {id:456, number:'1234', name:'Smith'} ];
var card = cards[0];
// each item is an instance of CreditCard
expect(card instanceof CreditCard).toEqual(true);
card.name = "J. Smith";
// non GET methods are mapped onto the instances
card.$save();
// POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'}
// server returns: {id:456, number:'1234', name: 'J. Smith'};
// our custom method is mapped as well.
card.$charge({amount:9.99});
// POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'}
});
// we can create an instance as well
var newCard = new CreditCard({number:'0123'});
newCard.name = "Mike Smith";
newCard.$save();
// POST: /user/123/card {number:'0123', name:'Mike Smith'}
// server returns: {id:789, number:'01234', name: 'Mike Smith'};
expect(newCard.id).toEqual(789);
* </pre>
*
* The object returned from this function execution is a resource "class" which has "static" method
* for each action in the definition.
*
* Calling these methods invoke `$http` on the `url` template with the given `method` and `params`.
* When the data is returned from the server then the object is an instance of the resource type and
* all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD
* operations (create, read, update, delete) on server-side data.
<pre>
var User = $resource('/user/:userId', {userId:'@id'});
var user = User.get({userId:123}, function() {
user.abc = true;
user.$save();
});
</pre>
*
* It's worth noting that the success callback for `get`, `query` and other method gets passed
* in the response that came from the server as well as $http header getter function, so one
* could rewrite the above example and get access to http headers as:
*
<pre>
var User = $resource('/user/:userId', {userId:'@id'});
User.get({userId:123}, function(u, getResponseHeaders){
u.abc = true;
u.$save(function(u, putResponseHeaders) {
//u => saved user object
//putResponseHeaders => $http header getter
});
});
</pre>
* # Buzz client
Let's look at what a buzz client created with the `$resource` service looks like:
<doc:example>
<doc:source jsfiddle="false">
<script>
function BuzzController($resource) {
this.userId = 'googlebuzz';
this.Activity = $resource(
'https://www.googleapis.com/buzz/v1/activities/:userId/:visibility/:activityId/:comments',
{alt:'json', callback:'JSON_CALLBACK'},
{get:{method:'JSONP', params:{visibility:'@self'}}, replies: {method:'JSONP', params:{visibility:'@self', comments:'@comments'}}}
);
}
BuzzController.prototype = {
fetch: function() {
this.activities = this.Activity.get({userId:this.userId});
},
expandReplies: function(activity) {
activity.replies = this.Activity.replies({userId:this.userId, activityId:activity.id});
}
};
BuzzController.$inject = ['$resource'];
</script>
<div ng-controller="BuzzController">
<input ng-model="userId"/>
<button ng-click="fetch()">fetch</button>
<hr/>
<div ng-repeat="item in activities.data.items">
<h1 style="font-size: 15px;">
<img src="{{item.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/>
<a href="{{item.actor.profileUrl}}">{{item.actor.name}}</a>
<a href ng-click="expandReplies(item)" style="float: right;">Expand replies: {{item.links.replies[0].count}}</a>
</h1>
{{item.object.content | html}}
<div ng-repeat="reply in item.replies.data.items" style="margin-left: 20px;">
<img src="{{reply.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/>
<a href="{{reply.actor.profileUrl}}">{{reply.actor.name}}</a>: {{reply.content | html}}
</div>
</div>
</div>
</doc:source>
<doc:scenario>
</doc:scenario>
</doc:example>
*/
angular.module('ngResource', ['ng']).
factory('$resource', ['$http', '$parse', function($http, $parse) {
var DEFAULT_ACTIONS = {
'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'}
};
var noop = angular.noop,
forEach = angular.forEach,
extend = angular.extend,
copy = angular.copy,
isFunction = angular.isFunction,
getter = function(obj, path) {
return $parse(path)(obj);
};
/**
* We need our custom method because encodeURIComponent is too aggressive and doesn't follow
* http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
* segments:
* segment = *pchar
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
* pct-encoded = "%" HEXDIG HEXDIG
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
* / "*" / "+" / "," / ";" / "="
*/
function encodeUriSegment(val) {
return encodeUriQuery(val, true).
replace(/%26/gi, '&').
replace(/%3D/gi, '=').
replace(/%2B/gi, '+');
}
/**
* This method is intended for encoding *key* or *value* parts of query component. We need a custom
* method becuase encodeURIComponent is too agressive and encodes stuff that doesn't have to be
* encoded per http://tools.ietf.org/html/rfc3986:
* query = *( pchar / "/" / "?" )
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
* pct-encoded = "%" HEXDIG HEXDIG
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
* / "*" / "+" / "," / ";" / "="
*/
function encodeUriQuery(val, pctEncodeSpaces) {
return encodeURIComponent(val).
replace(/%40/gi, '@').
replace(/%3A/gi, ':').
replace(/%24/g, '$').
replace(/%2C/gi, ',').
replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
}
function Route(template, defaults) {
this.template = template = template + '#';
this.defaults = defaults || {};
var urlParams = this.urlParams = {};
forEach(template.split(/\W/), function(param){
if (param && (new RegExp("(^|[^\\\\]):" + param + "\\W").test(template))) {
urlParams[param] = true;
}
});
this.template = template.replace(/\\:/g, ':');
}
Route.prototype = {
url: function(params) {
var self = this,
url = this.template,
val,
encodedVal;
params = params || {};
forEach(this.urlParams, function(_, urlParam){
val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
if (angular.isDefined(val) && val !== null) {
encodedVal = encodeUriSegment(val);
url = url.replace(new RegExp(":" + urlParam + "(\\W)", "g"), encodedVal + "$1");
} else {
url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W)", "g"), function(match,
leadingSlashes, tail) {
if (tail.charAt(0) == '/') {
return tail;
} else {
return leadingSlashes + tail;
}
});
}
});
url = url.replace(/\/?#$/, '');
var query = [];
forEach(params, function(value, key){
if (!self.urlParams[key]) {
query.push(encodeUriQuery(key) + '=' + encodeUriQuery(value));
}
});
query.sort();
url = url.replace(/\/*$/, '');
return url + (query.length ? '?' + query.join('&') : '');
}
};
function ResourceFactory(url, paramDefaults, actions) {
var route = new Route(url);
actions = extend({}, DEFAULT_ACTIONS, actions);
function extractParams(data, actionParams){
var ids = {};
actionParams = extend({}, paramDefaults, actionParams);
forEach(actionParams, function(value, key){
ids[key] = value.charAt && value.charAt(0) == '@' ? getter(data, value.substr(1)) : value;
});
return ids;
}
function Resource(value){
copy(value || {}, this);
}
forEach(actions, function(action, name) {
action.method = angular.uppercase(action.method);
var hasBody = action.method == 'POST' || action.method == 'PUT' || action.method == 'PATCH';
Resource[name] = function(a1, a2, a3, a4) {
var params = {};
var data;
var success = noop;
var error = null;
switch(arguments.length) {
case 4:
error = a4;
success = a3;
//fallthrough
case 3:
case 2:
if (isFunction(a2)) {
if (isFunction(a1)) {
success = a1;
error = a2;
break;
}
success = a2;
error = a3;
//fallthrough
} else {
params = a1;
data = a2;
success = a3;
break;
}
case 1:
if (isFunction(a1)) success = a1;
else if (hasBody) data = a1;
else params = a1;
break;
case 0: break;
default:
throw "Expected between 0-4 arguments [params, data, success, error], got " +
arguments.length + " arguments.";
}
var value = this instanceof Resource ? this : (action.isArray ? [] : new Resource(data));
$http({
method: action.method,
url: route.url(extend({}, extractParams(data, action.params || {}), params)),
data: data
}).then(function(response) {
var data = response.data;
if (data) {
if (action.isArray) {
value.length = 0;
forEach(data, function(item) {
value.push(new Resource(item));
});
} else {
copy(data, value);
}
}
(success||noop)(value, response.headers);
}, error);
return value;
};
Resource.prototype['$' + name] = function(a1, a2, a3) {
var params = extractParams(this),
success = noop,
error;
switch(arguments.length) {
case 3: params = a1; success = a2; error = a3; break;
case 2:
case 1:
if (isFunction(a1)) {
success = a1;
error = a2;
} else {
params = a1;
success = a2 || noop;
}
case 0: break;
default:
throw "Expected between 1-3 arguments [params, success, error], got " +
arguments.length + " arguments.";
}
var data = hasBody ? this : undefined;
Resource[name].call(this, params, data, success, error);
};
});
Resource.bind = function(additionalParamDefaults){
return ResourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions);
};
return Resource;
}
return ResourceFactory;
}]);
})(window, window.angular);

View file

@ -0,0 +1,537 @@
/**
* @license AngularJS v1.0.7
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
(function(window, angular, undefined) {
'use strict';
/**
* @ngdoc overview
* @name ngSanitize
* @description
*/
/*
* HTML Parser By Misko Hevery (misko@hevery.com)
* based on: HTML Parser By John Resig (ejohn.org)
* Original code by Erik Arvidsson, Mozilla Public License
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
*
* // Use like so:
* htmlParser(htmlString, {
* start: function(tag, attrs, unary) {},
* end: function(tag) {},
* chars: function(text) {},
* comment: function(text) {}
* });
*
*/
/**
* @ngdoc service
* @name ngSanitize.$sanitize
* @function
*
* @description
* The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are
* then serialized back to properly escaped html string. This means that no unsafe input can make
* it into the returned string, however, since our parser is more strict than a typical browser
* parser, it's possible that some obscure input, which would be recognized as valid HTML by a
* browser, won't make it through the sanitizer.
*
* @param {string} html Html input.
* @returns {string} Sanitized html.
*
* @example
<doc:example module="ngSanitize">
<doc:source>
<script>
function Ctrl($scope) {
$scope.snippet =
'<p style="color:blue">an html\n' +
'<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' +
'snippet</p>';
}
</script>
<div ng-controller="Ctrl">
Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
<table>
<tr>
<td>Filter</td>
<td>Source</td>
<td>Rendered</td>
</tr>
<tr id="html-filter">
<td>html filter</td>
<td>
<pre>&lt;div ng-bind-html="snippet"&gt;<br/>&lt;/div&gt;</pre>
</td>
<td>
<div ng-bind-html="snippet"></div>
</td>
</tr>
<tr id="escaped-html">
<td>no filter</td>
<td><pre>&lt;div ng-bind="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
<td><div ng-bind="snippet"></div></td>
</tr>
<tr id="html-unsafe-filter">
<td>unsafe html filter</td>
<td><pre>&lt;div ng-bind-html-unsafe="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
<td><div ng-bind-html-unsafe="snippet"></div></td>
</tr>
</table>
</div>
</doc:source>
<doc:scenario>
it('should sanitize the html snippet ', function() {
expect(using('#html-filter').element('div').html()).
toBe('<p>an html\n<em>click here</em>\nsnippet</p>');
});
it('should escape snippet without any filter', function() {
expect(using('#escaped-html').element('div').html()).
toBe("&lt;p style=\"color:blue\"&gt;an html\n" +
"&lt;em onmouseover=\"this.textContent='PWN3D!'\"&gt;click here&lt;/em&gt;\n" +
"snippet&lt;/p&gt;");
});
it('should inline raw snippet if filtered as unsafe', function() {
expect(using('#html-unsafe-filter').element("div").html()).
toBe("<p style=\"color:blue\">an html\n" +
"<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
"snippet</p>");
});
it('should update', function() {
input('snippet').enter('new <b>text</b>');
expect(using('#html-filter').binding('snippet')).toBe('new <b>text</b>');
expect(using('#escaped-html').element('div').html()).toBe("new &lt;b&gt;text&lt;/b&gt;");
expect(using('#html-unsafe-filter').binding("snippet")).toBe('new <b>text</b>');
});
</doc:scenario>
</doc:example>
*/
var $sanitize = function(html) {
var buf = [];
htmlParser(html, htmlSanitizeWriter(buf));
return buf.join('');
};
// Regular Expressions for parsing tags and attributes
var START_TAG_REGEXP = /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,
END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/,
ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
BEGIN_TAG_REGEXP = /^</,
BEGING_END_TAGE_REGEXP = /^<\s*\//,
COMMENT_REGEXP = /<!--(.*?)-->/g,
CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
URI_REGEXP = /^((ftp|https?):\/\/|mailto:|#)/,
NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; // Match everything outside of normal chars and " (quote character)
// Good source of info about elements and attributes
// http://dev.w3.org/html5/spec/Overview.html#semantics
// http://simon.html5.org/html-elements
// Safe Void Elements - HTML5
// http://dev.w3.org/html5/spec/Overview.html#void-elements
var voidElements = makeMap("area,br,col,hr,img,wbr");
// Elements that you can, intentionally, leave open (and which close themselves)
// http://dev.w3.org/html5/spec/Overview.html#optional-tags
var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),
optionalEndTagInlineElements = makeMap("rp,rt"),
optionalEndTagElements = angular.extend({}, optionalEndTagInlineElements, optionalEndTagBlockElements);
// Safe Block Elements - HTML5
var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article,aside," +
"blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6," +
"header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));
// Inline Elements - HTML5
var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b,bdi,bdo," +
"big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small," +
"span,strike,strong,sub,sup,time,tt,u,var"));
// Special Elements (can contain anything)
var specialElements = makeMap("script,style");
var validElements = angular.extend({}, voidElements, blockElements, inlineElements, optionalEndTagElements);
//Attributes that have href and hence need to be sanitized
var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap");
var validAttrs = angular.extend({}, uriAttrs, makeMap(
'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+
'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+
'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+
'scope,scrolling,shape,span,start,summary,target,title,type,'+
'valign,value,vspace,width'));
function makeMap(str) {
var obj = {}, items = str.split(','), i;
for (i = 0; i < items.length; i++) obj[items[i]] = true;
return obj;
}
/**
* @example
* htmlParser(htmlString, {
* start: function(tag, attrs, unary) {},
* end: function(tag) {},
* chars: function(text) {},
* comment: function(text) {}
* });
*
* @param {string} html string
* @param {object} handler
*/
function htmlParser( html, handler ) {
var index, chars, match, stack = [], last = html;
stack.last = function() { return stack[ stack.length - 1 ]; };
while ( html ) {
chars = true;
// Make sure we're not in a script or style element
if ( !stack.last() || !specialElements[ stack.last() ] ) {
// Comment
if ( html.indexOf("<!--") === 0 ) {
index = html.indexOf("-->");
if ( index >= 0 ) {
if (handler.comment) handler.comment( html.substring( 4, index ) );
html = html.substring( index + 3 );
chars = false;
}
// end tag
} else if ( BEGING_END_TAGE_REGEXP.test(html) ) {
match = html.match( END_TAG_REGEXP );
if ( match ) {
html = html.substring( match[0].length );
match[0].replace( END_TAG_REGEXP, parseEndTag );
chars = false;
}
// start tag
} else if ( BEGIN_TAG_REGEXP.test(html) ) {
match = html.match( START_TAG_REGEXP );
if ( match ) {
html = html.substring( match[0].length );
match[0].replace( START_TAG_REGEXP, parseStartTag );
chars = false;
}
}
if ( chars ) {
index = html.indexOf("<");
var text = index < 0 ? html : html.substring( 0, index );
html = index < 0 ? "" : html.substring( index );
if (handler.chars) handler.chars( decodeEntities(text) );
}
} else {
html = html.replace(new RegExp("(.*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'), function(all, text){
text = text.
replace(COMMENT_REGEXP, "$1").
replace(CDATA_REGEXP, "$1");
if (handler.chars) handler.chars( decodeEntities(text) );
return "";
});
parseEndTag( "", stack.last() );
}
if ( html == last ) {
throw "Parse Error: " + html;
}
last = html;
}
// Clean up any remaining tags
parseEndTag();
function parseStartTag( tag, tagName, rest, unary ) {
tagName = angular.lowercase(tagName);
if ( blockElements[ tagName ] ) {
while ( stack.last() && inlineElements[ stack.last() ] ) {
parseEndTag( "", stack.last() );
}
}
if ( optionalEndTagElements[ tagName ] && stack.last() == tagName ) {
parseEndTag( "", tagName );
}
unary = voidElements[ tagName ] || !!unary;
if ( !unary )
stack.push( tagName );
var attrs = {};
rest.replace(ATTR_REGEXP, function(match, name, doubleQuotedValue, singleQoutedValue, unqoutedValue) {
var value = doubleQuotedValue
|| singleQoutedValue
|| unqoutedValue
|| '';
attrs[name] = decodeEntities(value);
});
if (handler.start) handler.start( tagName, attrs, unary );
}
function parseEndTag( tag, tagName ) {
var pos = 0, i;
tagName = angular.lowercase(tagName);
if ( tagName )
// Find the closest opened tag of the same type
for ( pos = stack.length - 1; pos >= 0; pos-- )
if ( stack[ pos ] == tagName )
break;
if ( pos >= 0 ) {
// Close all the open elements, up the stack
for ( i = stack.length - 1; i >= pos; i-- )
if (handler.end) handler.end( stack[ i ] );
// Remove the open elements from the stack
stack.length = pos;
}
}
}
/**
* decodes all entities into regular string
* @param value
* @returns {string} A string with decoded entities.
*/
var hiddenPre=document.createElement("pre");
function decodeEntities(value) {
hiddenPre.innerHTML=value.replace(/</g,"&lt;");
return hiddenPre.innerText || hiddenPre.textContent || '';
}
/**
* Escapes all potentially dangerous characters, so that the
* resulting string can be safely inserted into attribute or
* element text.
* @param value
* @returns escaped text
*/
function encodeEntities(value) {
return value.
replace(/&/g, '&amp;').
replace(NON_ALPHANUMERIC_REGEXP, function(value){
return '&#' + value.charCodeAt(0) + ';';
}).
replace(/</g, '&lt;').
replace(/>/g, '&gt;');
}
/**
* create an HTML/XML writer which writes to buffer
* @param {Array} buf use buf.jain('') to get out sanitized html string
* @returns {object} in the form of {
* start: function(tag, attrs, unary) {},
* end: function(tag) {},
* chars: function(text) {},
* comment: function(text) {}
* }
*/
function htmlSanitizeWriter(buf){
var ignore = false;
var out = angular.bind(buf, buf.push);
return {
start: function(tag, attrs, unary){
tag = angular.lowercase(tag);
if (!ignore && specialElements[tag]) {
ignore = tag;
}
if (!ignore && validElements[tag] == true) {
out('<');
out(tag);
angular.forEach(attrs, function(value, key){
var lkey=angular.lowercase(key);
if (validAttrs[lkey]==true && (uriAttrs[lkey]!==true || value.match(URI_REGEXP))) {
out(' ');
out(key);
out('="');
out(encodeEntities(value));
out('"');
}
});
out(unary ? '/>' : '>');
}
},
end: function(tag){
tag = angular.lowercase(tag);
if (!ignore && validElements[tag] == true) {
out('</');
out(tag);
out('>');
}
if (tag == ignore) {
ignore = false;
}
},
chars: function(chars){
if (!ignore) {
out(encodeEntities(chars));
}
}
};
}
// define ngSanitize module and register $sanitize service
angular.module('ngSanitize', []).value('$sanitize', $sanitize);
/**
* @ngdoc directive
* @name ngSanitize.directive:ngBindHtml
*
* @description
* Creates a binding that will sanitize the result of evaluating the `expression` with the
* {@link ngSanitize.$sanitize $sanitize} service and innerHTML the result into the current element.
*
* See {@link ngSanitize.$sanitize $sanitize} docs for examples.
*
* @element ANY
* @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate.
*/
angular.module('ngSanitize').directive('ngBindHtml', ['$sanitize', function($sanitize) {
return function(scope, element, attr) {
element.addClass('ng-binding').data('$binding', attr.ngBindHtml);
scope.$watch(attr.ngBindHtml, function ngBindHtmlWatchAction(value) {
value = $sanitize(value);
element.html(value || '');
});
};
}]);
/**
* @ngdoc filter
* @name ngSanitize.filter:linky
* @function
*
* @description
* Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and
* plain email address links.
*
* @param {string} text Input text.
* @returns {string} Html-linkified text.
*
* @usage
<span ng-bind-html="linky_expression | linky"></span>
*
* @example
<doc:example module="ngSanitize">
<doc:source>
<script>
function Ctrl($scope) {
$scope.snippet =
'Pretty text with some links:\n'+
'http://angularjs.org/,\n'+
'mailto:us@somewhere.org,\n'+
'another@somewhere.org,\n'+
'and one more: ftp://127.0.0.1/.';
}
</script>
<div ng-controller="Ctrl">
Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
<table>
<tr>
<td>Filter</td>
<td>Source</td>
<td>Rendered</td>
</tr>
<tr id="linky-filter">
<td>linky filter</td>
<td>
<pre>&lt;div ng-bind-html="snippet | linky"&gt;<br>&lt;/div&gt;</pre>
</td>
<td>
<div ng-bind-html="snippet | linky"></div>
</td>
</tr>
<tr id="escaped-html">
<td>no filter</td>
<td><pre>&lt;div ng-bind="snippet"&gt;<br>&lt;/div&gt;</pre></td>
<td><div ng-bind="snippet"></div></td>
</tr>
</table>
</doc:source>
<doc:scenario>
it('should linkify the snippet with urls', function() {
expect(using('#linky-filter').binding('snippet | linky')).
toBe('Pretty text with some links:&#10;' +
'<a href="http://angularjs.org/">http://angularjs.org/</a>,&#10;' +
'<a href="mailto:us@somewhere.org">us@somewhere.org</a>,&#10;' +
'<a href="mailto:another@somewhere.org">another@somewhere.org</a>,&#10;' +
'and one more: <a href="ftp://127.0.0.1/">ftp://127.0.0.1/</a>.');
});
it ('should not linkify snippet without the linky filter', function() {
expect(using('#escaped-html').binding('snippet')).
toBe("Pretty text with some links:\n" +
"http://angularjs.org/,\n" +
"mailto:us@somewhere.org,\n" +
"another@somewhere.org,\n" +
"and one more: ftp://127.0.0.1/.");
});
it('should update', function() {
input('snippet').enter('new http://link.');
expect(using('#linky-filter').binding('snippet | linky')).
toBe('new <a href="http://link">http://link</a>.');
expect(using('#escaped-html').binding('snippet')).toBe('new http://link.');
});
</doc:scenario>
</doc:example>
*/
angular.module('ngSanitize').filter('linky', function() {
var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}\<\>]/,
MAILTO_REGEXP = /^mailto:/;
return function(text) {
if (!text) return text;
var match;
var raw = text;
var html = [];
// TODO(vojta): use $sanitize instead
var writer = htmlSanitizeWriter(html);
var url;
var i;
while ((match = raw.match(LINKY_URL_REGEXP))) {
// We can not end in these as they are sometimes found at the end of the sentence
url = match[0];
// if we did not match ftp/http/mailto then assume mailto
if (match[2] == match[3]) url = 'mailto:' + url;
i = match.index;
writer.chars(raw.substr(0, i));
writer.start('a', {href:url});
writer.chars(match[0].replace(MAILTO_REGEXP, ''));
writer.end('a');
raw = raw.substring(i + match[0].length);
}
writer.chars(raw);
return html.join('');
};
});
})(window, window.angular);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,6 @@
/**
* Configuration for jstd scenario adapter
*/
var jstdScenarioAdapter = {
relativeUrlPrefix: '/build/docs/'
};

View file

@ -0,0 +1,185 @@
/**
* @license AngularJS v1.0.5
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
(function(window) {
'use strict';
/**
* JSTestDriver adapter for angular scenario tests
*
* Example of jsTestDriver.conf for running scenario tests with JSTD:
<pre>
server: http://localhost:9877
load:
- lib/angular-scenario.js
- lib/jstd-scenario-adapter-config.js
- lib/jstd-scenario-adapter.js
# your test files go here #
proxy:
- {matcher: "/your-prefix/*", server: "http://localhost:8000/"}
</pre>
*
* For more information on how to configure jstd proxy, see {@link http://code.google.com/p/js-test-driver/wiki/Proxy}
* Note the order of files - it's important !
*
* Example of jstd-scenario-adapter-config.js
<pre>
var jstdScenarioAdapter = {
relativeUrlPrefix: '/your-prefix/'
};
</pre>
*
* Whenever you use <code>browser().navigateTo('relativeUrl')</code> in your scenario test, the relativeUrlPrefix will be prepended.
* You have to configure this to work together with JSTD proxy.
*
* Let's assume you are using the above configuration (jsTestDriver.conf and jstd-scenario-adapter-config.js):
* Now, when you call <code>browser().navigateTo('index.html')</code> in your scenario test, the browser will open /your-prefix/index.html.
* That matches the proxy, so JSTD will proxy this request to http://localhost:8000/index.html.
*/
/**
* Custom type of test case
*
* @const
* @see jstestdriver.TestCaseInfo
*/
var SCENARIO_TYPE = 'scenario';
/**
* Plugin for JSTestDriver
* Connection point between scenario's jstd output and jstestdriver.
*
* @see jstestdriver.PluginRegistrar
*/
function JstdPlugin() {
var nop = function() {};
this.reportResult = nop;
this.reportEnd = nop;
this.runScenario = nop;
this.name = 'Angular Scenario Adapter';
/**
* Called for each JSTD TestCase
*
* Handles only SCENARIO_TYPE test cases. There should be only one fake TestCase.
* Runs all scenario tests (under one fake TestCase) and report all results to JSTD.
*
* @param {jstestdriver.TestRunConfiguration} configuration
* @param {Function} onTestDone
* @param {Function} onAllTestsComplete
* @returns {boolean} True if this type of test is handled by this plugin, false otherwise
*/
this.runTestConfiguration = function(configuration, onTestDone, onAllTestsComplete) {
if (configuration.getTestCaseInfo().getType() != SCENARIO_TYPE) return false;
this.reportResult = onTestDone;
this.reportEnd = onAllTestsComplete;
this.runScenario();
return true;
};
this.getTestRunsConfigurationFor = function(testCaseInfos, expressions, testRunsConfiguration) {
testRunsConfiguration.push(
new jstestdriver.TestRunConfiguration(
new jstestdriver.TestCaseInfo(
'Angular Scenario Tests', function() {}, SCENARIO_TYPE), []));
return true;
};
}
/**
* Singleton instance of the plugin
* Accessed using closure by:
* - jstd output (reports to this plugin)
* - initScenarioAdapter (register the plugin to jstd)
*/
var plugin = new JstdPlugin();
/**
* Initialise scenario jstd-adapter
* (only if jstestdriver is defined)
*
* @param {Object} jstestdriver Undefined when run from browser (without jstd)
* @param {Function} initScenarioAndRun Function that inits scenario and runs all the tests
* @param {Object=} config Configuration object, supported properties:
* - relativeUrlPrefix: prefix for all relative links when navigateTo()
*/
function initScenarioAdapter(jstestdriver, initScenarioAndRun, config) {
if (jstestdriver) {
// create and register ScenarioPlugin
jstestdriver.pluginRegistrar.register(plugin);
plugin.runScenario = initScenarioAndRun;
/**
* HACK (angular.scenario.Application.navigateTo)
*
* We need to navigate to relative urls when running from browser (without JSTD),
* because we want to allow running scenario tests without creating its own virtual host.
* For example: http://angular.local/build/docs/docs-scenario.html
*
* On the other hand, when running with JSTD, we need to navigate to absolute urls,
* because of JSTD proxy. (proxy, because of same domain policy)
*
* So this hack is applied only if running with JSTD and change all relative urls to absolute.
*/
var appProto = angular.scenario.Application.prototype,
navigateTo = appProto.navigateTo,
relativeUrlPrefix = config && config.relativeUrlPrefix || '/';
appProto.navigateTo = function(url, loadFn, errorFn) {
if (url.charAt(0) != '/' && url.charAt(0) != '#' &&
url != 'about:blank' && !url.match(/^https?/)) {
url = relativeUrlPrefix + url;
}
return navigateTo.call(this, url, loadFn, errorFn);
};
}
}
/**
* Builds proper TestResult object from given model spec
*
* TODO(vojta) report error details
*
* @param {angular.scenario.ObjectModel.Spec} spec
* @returns {jstestdriver.TestResult}
*/
function createTestResultFromSpec(spec) {
var map = {
success: 'PASSED',
error: 'ERROR',
failure: 'FAILED'
};
return new jstestdriver.TestResult(
spec.fullDefinitionName,
spec.name,
jstestdriver.TestResult.RESULT[map[spec.status]],
spec.error || '',
spec.line || '',
spec.duration);
}
/**
* Generates JSTD output (jstestdriver.TestResult)
*/
angular.scenario.output('jstd', function(context, runner, model) {
model.on('SpecEnd', function(spec) {
plugin.reportResult(createTestResultFromSpec(spec));
});
model.on('RunnerEnd', function() {
plugin.reportEnd();
});
});
initScenarioAdapter(window.jstestdriver, angular.scenario.setUpAndRun, window.jstdScenarioAdapter);
})(window);

View file

@ -0,0 +1 @@
{"full":"1.0.7","major":"1","minor":"0","dot":"7","codename":"monochromatic-rainbow","cdn":"1.0.6"}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,109 @@
<div id="wrapper" class="container">
<div class="row">
<aside class="span3" data-ng-include data-src="'partials/application-menu.html'"></aside>
<div id="actions-bg"></div>
<div id="container-right" class="span9">
<h1 data-ng-show="create"><span class="gray">New Application</span></h1>
<h1 data-ng-hide="create">
<span class="gray">{{application.name}}</span> configuration
</h1>
<div data-ng-show="applicationForm.showErrors && applicationForm.$error.required" class="alert alert-error">
Please fill in all required fields
</div>
<p class="subtitle subtitle-right"><span class="required">*</span> Required fields</p>
<form class="form-horizontal" name="applicationForm" novalidate>
<fieldset>
<legend>Settings</legend>
<div data-kc-input>
<label>Name</label>
<input class="input-xlarge" type="text" name="name" data-ng-model="application.name" autofocus
required>
</div>
<div data-kc-input>
<label>Enabled</label>
<input class="input-xlarge" type="checkbox" name="enabled" data-ng-model="application.enabled">
</div>
<div class="control-group">
<label class="control-label" for="realm">Realm <span class="required">*</span></label>
<div class="controls">
<select data-ng-model="application.realm" id="realm" name="realm" data-ng-required>
<option data-ng-repeat="r in realms" value="{{r.id}}"
data-ng-selected="r.id == application.realm">{{r.name}}
</option>
</select>
</div>
</div>
</fieldset>
<fieldset>
<legend>Roles</legend>
<div class="control-group">
<label class="control-label">Roles</label>
<div class="controls">
<span class="label" style="margin-right: 1em;"
data-ng-repeat="r in (application.roles|orderBy:'toString()')">{{r}} <button
data-ng-click="removeRole(r)"><i class="icon-remove icon-white"></i></button></span>
<div class="input-append">
<input class="input-small" type="text" data-ng-model="newRole" placeHolder="Role"
data-kc-enter="addRole()"/>
<button class="btn" type="button" data-ng-click="addRole()">Add</button>
</div>
</div>
</div>
<div class="control-group">
<label class="control-label">Initial Roles</label>
<div class="controls">
<span class="label" style="margin-right: 1em;"
data-ng-repeat="r in (application.initialRoles|orderBy:'toString()')">{{r}} <button
data-ng-click="removeInitialRole(r)"><i class="icon-remove icon-white"></i></button></span>
<div class="input-append">
<select style="width: auto;" data-ng-model="newInitialRole"
data-ng-click="addInitialRole()">
<option data-ng-repeat="r in (application.roles|remove:application.initialRoles|orderBy:'toString()')"
value="{{r}}">{{r}}
</option>
</select>
</div>
</div>
</div>
</fieldset>
<div class="form-actions" data-ng-show="create">
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
</button>
<button type="submit" data-ng-click="cancel()" class="btn" data-ng-click="cancel()"
data-ng-show="changed">Cancel
</button>
</div>
<div class="form-actions" data-ng-show="!create">
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
changes
</button>
<button type="submit" data-ng-click="reset()" class="btn" data-ng-show="changed">Clear changes
</button>
<a href="#/applications" data-ng-hide="changed">View applications &#187;</a>
<button type="submit" data-ng-click="remove()" class="btn btn-danger" data-ng-hide="changed">
Delete
</button>
</div>
</form>
</div>
<div id="container-right-bg"></div>
</div>
</div>

View file

@ -0,0 +1,26 @@
<div id="wrapper" class="container">
<div class="row">
<aside class="span3" data-ng-include data-src="'partials/application-menu.html'"></aside>
<div id="actions-bg"></div>
<div id="container-right" class="span9">
<a class="btn btn-small pull-right" href="#/create/application">Add Application</a>
<h1>
<span class="gray">Applications</span>
</h1>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Application</th>
</tr>
</thead>
<tr data-ng-repeat="application in applications">
<td><a href="#/applications/{{application.id}}">{{application.name}}</a></td>
</tr>
</table>
</div>
<div id="container-right-bg"></div>
</div>
</div>

View file

@ -0,0 +1,20 @@
<nav id="local-nav" data-ng-controller="ApplicationListCtrl">
<ul class="nav nav-list">
<li>
<div>
<span class="toggle">Applications</span>
</div>
<ul>
<li data-ng-repeat="a in applications" data-ng-class="path[1] == a.id && 'active'">
<a href="#/applications/{{a.id}}">{{a.name}}</a>
<ul class="sub-items" data-ng-show="path[1] == a.id">
<li data-ng-class="!path[2] && 'active'"><a href="#/applications/{{a.id}}">Configuration</a>
</li>
<li data-ng-class="path[2] == 'roles' && 'active'"><a href="#/applications/{{a.id}}/roles">Role
mapping</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>

View file

@ -0,0 +1,4 @@
<div id="wrapper" class="container">
<div class="row">
</div>
</div>

View file

@ -0,0 +1,30 @@
<header class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<div class="nav-collapse">
<nav id="global-nav">
<ul class="nav">
<li class="divider-vertical-left" data-ng-class="path[0] == '' && 'active'"><a href="#">Home</a>
</li>
<li class="divider-vertical-left" data-ng-class="path[0] == 'applications' && 'active'"
data-ng-show="auth.loggedIn"><a href="#/applications">Applications</a></li>
<li class="divider-vertical-left" data-ng-class="path[0] == 'realms' && 'active'"
data-ng-show="auth.loggedIn"><a href="#/realms">Realms</a></li>
</ul>
<ul class="nav pull-right" data-ng-hide="auth.loggedIn">
<li><a href="/auth-server/saas/saas-login.jsp">Login</a></li>
<li><a href="/ejs-identity/api/register/system">Register</a></li>
</ul>
<ul class="nav pull-right" data-ng-show="auth.loggedIn">
<li class="dropdown"><a data-toggle="dropdown" class="dropdown-toggle" href="#"><i
class="icon-user icon-gray"></i> {{auth.user.displayName}} <i class="caret"></i></a>
<ul class="dropdown-menu">
<li><a href="/auth-server/rest/saas/logout" >Sign Out</a></li> <!--data-ng-click="auth.logout()" -->
</ul>
</li>
</ul>
</nav>
</div>
</div>
</div>
</header>

View file

@ -0,0 +1,40 @@
<p>
Open <a href="https://code.google.com/apis/console/" target="_blank">https://code.google.com/apis/console/</a>. From
the
drop-down menu select <i>Create</i>.
</p>
<p>Use any name that you'd like, click <i>Create Project</i>, select <i>API Access</i> and click on <i>Create an OAuth
2.0 client ID</i>.</p>
<p>Use any product name you'd like and leave the other fields empty, then click <i>Next</i>. On the next page select <i>Web
application</i>
as the application type. Click <i>more options</i> next to <i>Your site or hostname</i>. Fill in the form with the
following values:</p>
<ul>
<li><b>Authorized Redirect URIs:</b> {{callbackUrl}}</li>
</ul>
<p>Click on <i>Create client ID</i>. Insert <i>Client ID</i> and <i>Client secret</i> in the form below.</p>
<form class="form-horizontal" name="googleHelpForm">
<div class="control-group">
<label class="control-label" for="providerHelp.key">Client ID </label>
<div class="controls">
<input type="text" class="input-xlarge" id="providerHelp.key"
data-ng-model="application.providers[providerHelp.index].key">
</div>
</div>
<div class="control-group">
<label class="control-label" for="providerHelp.secret">Client secret </label>
<div class="controls">
<input type="text" class="input-xlarge" id="providerHelp.secret"
data-ng-model="application.providers[providerHelp.index].secret">
</div>
</div>
</form>
<p>Close the help panel and click <i>save changes</i>.</p>

View file

@ -0,0 +1,46 @@
<p>
Open <a href="https://dev.twitter.com/apps" target="_blank">https://dev.twitter.com/apps</a>. Click on <i>Create a
new
application</i>.
</p>
<p>Fill in name, description and website. For <i>Callback URL</i> use the following value:</p>
<ul>
<li><b>Callback URL:</b> {{callbackUrl}}</li>
</ul>
<p>Note: Twitter doesn't allow <b>localhost</b> as domain, use <b>127.0.0.1</b> instead!</p>
<p>Agree to the rules, fill in the captcha and click on <i>Create your Twitter application</i></p>
<p>Insert <i>Consumer key</i> and <i>Consumer secret</i> in the form below.</p>
<form class="form-horizontal" name="googleHelpForm">
<div class="control-group">
<label class="control-label" for="providerHelp.key">Consumer key </label>
<div class="controls">
<input type="text" class="input-xlarge" id="providerHelp.key"
data-ng-model="application.providers[providerHelp.index].key">
</div>
</div>
<div class="control-group">
<label class="control-label" for="providerHelp.secret">Consumer secret </label>
<div class="controls">
<input type="text" class="input-xlarge" id="providerHelp.secret"
data-ng-model="application.providers[providerHelp.index].secret">
</div>
</div>
</form>
<p>
Now click on <i>Settings</i> and tick the box <i>Allow this application to be used to Sign in with Twitter</i>, and
click on <i>Update
this Twitter application's settings</i>.
</p>
<p>
Close the help panel and click <i>save changes</i>.
</p>

View file

@ -0,0 +1,149 @@
<div id="wrapper" class="container">
<div class="row">
<aside class="span3" data-ng-include data-src="'partials/realm-menu.html'"></aside>
<div id="actions-bg"></div>
<div id="container-right" class="span9">
<h1 data-ng-show="create"><span class="gray">New Realm</span></h1>
<h1 data-ng-hide="create">
<span class="gray">{{realm.realm}}</span> configuration
</h1>
<div data-ng-show="realmForm.showErrors && realmForm.$error.required" class="alert alert-error">Please fill
in all required fields
</div>
<p class="subtitle subtitle-right"><span class="required">*</span> Required fields</p>
<form class="form-horizontal" name="realmForm" novalidate>
<fieldset>
<legend>Settings</legend>
<div data-kc-input>
<label>Name</label>
<input class="input-xlarge" type="text" name="name" data-ng-model="realm.name" autofocus
required>
</div>
<div data-kc-input>
<label>Enabled</label>
<input class="input-xlarge" type="checkbox" name="enabled" data-ng-model="realm.enabled">
</div>
<div data-kc-input>
<label>Social login</label>
<input class="input-xlarge" type="checkbox" name="social" data-ng-model="realm.social">
</div>
<div data-kc-input>
<label>Require SSL</label>
<input class="input-xlarge" type="checkbox" name="requireSsl" data-ng-model="realm.requireSsl">
</div>
<div data-kc-input>
<label>Cookie login allowed</label>
<input class="input-xlarge" type="checkbox" name="cookieLoginAllowed" data-ng-model="realm.cookieLoginAllowed">
</div>
<div data-kc-input>
<label>User registration</label>
<input class="input-xlarge" type="checkbox" name="social"
data-ng-model="realm.userRegistration">
</div>
<div class="control-group">
<label for="realmForm-tokenLifespan" class="control-label">Token lifespan</label>
<div class="controls">
<input class="input-small" type="text" name="tokenLifespan"
data-ng-model="realm.tokenLifespan">
<select style="width: auto;" name="tokenLifespanUnit"
data-ng-model="realm.tokenLifespanUnit">
<option value="SECONDS" data-ng-selected="!realm.tokenLifespanUnit">Seconds</option>
<option value="MINUTES">Minutes</option>
<option value="HOURS">Hours</option>
<option value="DAYS">Days</option>
</select>
</div>
</div>
<div class="control-group">
<label for="realmForm-accessCodeLifespan" class="control-label">Access code lifespan</label>
<div class="controls">
<input class="input-small" type="text" name="accessCodeLifespan"
data-ng-model="realm.accessCodeLifespan">
<select style="width: auto;" name="accessCodeLifespanUnit"
data-ng-model="realm.accessCodeLifespanUnit">
<option value="SECONDS" data-ng-selected="!realm.accessCodeLifespanUnit">Seconds</option>
<option value="MINUTES">Minutes</option>
<option value="HOURS">Hours</option>
<option value="DAYS">Days</option>
</select>
</div>
</div>
</fieldset>
<fieldset>
<legend>Roles</legend>
<div class="control-group">
<label class="control-label">Roles</label>
<div class="controls">
<span class="label" style="margin-right: 1em;"
data-ng-repeat="r in (realm.roles|orderBy:'toString()')">{{r}} <button
data-ng-click="removeRole(r)"><i class="icon-remove icon-white"></i></button></span>
<div class="input-append">
<input class="input-small" type="text" data-ng-model="newRole" placeHolder="Role"
data-kc-enter="addRole()"/>
<button class="btn" type="button" data-ng-click="addRole()">Add</button>
</div>
</div>
</div>
<div class="control-group">
<label class="control-label">Initial Roles</label>
<div class="controls">
<span class="label" style="margin-right: 1em;"
data-ng-repeat="r in (realm.initialRoles|orderBy:'toString()')">{{r}} <button
data-ng-click="removeInitialRole(r)"><i class="icon-remove icon-white"></i></button></span>
<div class="input-append">
<select style="width: auto;" data-ng-model="newInitialRole"
data-ng-click="addInitialRole()">
<option data-ng-repeat="r in (realm.roles|remove:realm.initialRoles|orderBy:'toString()')"
value="{{r}}">{{r}}
</option>
</select>
</div>
</div>
</div>
</fieldset>
<div class="form-actions" data-ng-show="create">
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
</button>
<button type="submit" data-ng-click="cancel()" class="btn" data-ng-click="cancel()"
data-ng-show="changed">Cancel
</button>
</div>
<div class="form-actions" data-ng-show="!create">
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
changes
</button>
<button type="submit" data-ng-click="reset()" class="btn" data-ng-show="changed">Clear changes
</button>
<a href="#/realms" data-ng-hide="changed">View realms &#187;</a>
<button type="submit" data-ng-click="remove()" class="btn btn-danger" data-ng-hide="changed">
Delete
</button>
</div>
</form>
</div>
<div id="container-right-bg"></div>
</div>
</div>

View file

@ -0,0 +1,27 @@
<div id="wrapper" class="container">
<div class="row">
<aside class="span3" data-ng-include data-src="'partials/realm-menu.html'"></aside>
<div id="actions-bg"></div>
<div id="container-right" class="span9">
<a class="btn btn-small pull-right" href="#/create/realm">Add Realm</a>
<h1>
<span class="gray">Realms</span>
</h1>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Realm</th>
</tr>
</thead>
<tr data-ng-repeat="(id, name) in realms">
<td><a href="#/realms/{{id}}">{{name}}</a></td>
</tr>
</table>
</div>
<div id="container-right-bg"></div>
</div>
</div>

View file

@ -0,0 +1,21 @@
<nav id="local-nav" data-ng-controller="RealmListCtrl">
<ul class="nav nav-list">
<li>
<div>
<span class="toggle">Realms</span>
</div>
<ul>
<li data-ng-repeat="r in realms" data-ng-class="path[1] == r.id && 'active'">
<a href=#/realms/{{r.id}}>{{r.name}}</a>
<ul class="sub-items" data-ng-show="path[1] == r.id">
<li data-ng-class="!path[2] && 'active'"><a href="#/realms/{{r.id}}">Configuration</a></li>
<li data-ng-class="path[2] == 'users' && 'active'"><a href="#/realms/{{r.id}}/users">Users</a>
</li>
<li data-ng-class="path[2] == 'roles' && 'active'"><a href="#/realms/{{r.id}}/roles">Role
mapping</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>

View file

@ -0,0 +1,50 @@
<div id="wrapper" class="container">
<div class="row">
<aside class="span3" data-ng-include data-src="'partials/' + path[0].slice(0, -1) + '-menu.html'"></aside>
<div id="actions-bg"></div>
<div id="container-right" class="span9">
<h1>
<span class="gray" data-ng-hide="create">{{realm.name}}</span> role mapping
</h1>
<ul class="nav nav-tabs">
<li data-ng-class="path[3] == r && 'active'" data-ng-repeat="r in (realm.roles|orderBy:'toString()')"><a
href="#/{{path[0]}}/{{realm.id}}/roles/{{r}}">{{r}}</a></li>
</ul>
<div data-ng-show="role">
<select style="width: auto;" id="realm" name="realm" data-ng-model="newUser" data-ng-click="addUser(u)">
<option data-ng-repeat="u in (allUsers|remove:users:'userId')" value="{{u.userId}}">{{u.userId}}
</option>
</select>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Username</th>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tr data-ng-repeat="user in users">
<td>{{user.userId}}</td>
<td>{{user.firstName}}</td>
<td>{{user.lastName}}</td>
<td>{{user.email}}</td>
<td>
<button data-ng-click="removeUser(user.userId)">
<i class="icon-remove"></i>
</button>
</td>
</tr>
</table>
</div>
</div>
<div id="container-right-bg"></div>
</div>
</div>

View file

@ -0,0 +1,107 @@
<div id="wrapper" class="container">
<div class="row">
<aside class="span3" data-ng-include data-src="'partials/realm-menu.html'"></aside>
<div id="actions-bg"></div>
<div id="container-right" class="span9">
<h1 data-ng-show="create"><span class="gray">New User</span></h1>
<h1 data-ng-hide="create">
<span class="gray">{{user.userId}}</span> configuration
</h1>
<div data-ng-show="userForm.showErrors && userForm.$error.required" class="alert alert-error">Please fill in
all required fields
</div>
<p class="subtitle subtitle-right"><span class="required">*</span> Required fields</p>
<form class="form-horizontal" name="userForm" novalidate>
<fieldset>
<legend>Details</legend>
<div class="control-group">
<label class="control-label" for="name">Username <span class="required">*</span></label>
<div class="controls">
<input type="text" class="input-xlarge" id="name" name="name" data-ng-model="user.userId"
autofocus required data-ng-readonly="!create">
</div>
</div>
<div class="control-group">
<label class="control-label" for="email">Email </label>
<div class="controls">
<input type="email" class="input-xlarge" id="email" name="email" data-ng-model="user.email">
<span class="help-inline error"
data-ng-show="userForm.showErrors && userForm.email.$invalid">Invalid email</span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="firstName">Firstname </label>
<div class="controls">
<input type="text" class="input-xlarge" id="firstName" data-ng-model="user.firstName">
</div>
</div>
<div class="control-group">
<label class="control-label" for="lastName">Lastname </label>
<div class="controls">
<input type="text" class="input-xlarge" id="lastName" data-ng-model="user.lastName">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">Password <span class="required">*</span></label>
<div class="controls">
<input type="password" class="input-xlarge" id="password" name="password"
data-ng-model="user.password" data-ng-required="create">
</div>
</div>
</fieldset>
<fieldset data-ng-show="user.attributes.length > 0">
<legend>Attributes</legend>
<table class="table table-striped table-bordered margin-top">
<thead>
<tr>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tr data-ng-repeat="attribute in user.attributes">
<td><input type="text" placeholder="Name" value="{{attribute.name}}" readonly></td>
<td><input type="text" placeholder="Value" value="{{attribute.value}}" readonly></td>
</tr>
</table>
</fieldset>
<div class="form-actions" data-ng-show="create">
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
</button>
<button type="submit" data-ng-click="cancel()" class="btn" data-ng-click="cancel()"
data-ng-show="changed">Cancel
</button>
</div>
<div class="form-actions" data-ng-show="!create">
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
changes
</button>
<button type="submit" data-ng-click="reset()" class="btn" data-ng-show="changed">Clear changes
</button>
<a href="#/realms/{{realm.id}}/users" data-ng-hide="changed">View users &#187;</a>
<button type="submit" data-ng-click="remove()" class="btn btn-danger" data-ng-hide="changed">
Delete
</button>
</div>
</form>
</div>
<div id="container-right-bg"></div>
</div>
</div>

View file

@ -0,0 +1,32 @@
<div id="wrapper" class="container">
<div class="row">
<aside class="span3" data-ng-include data-src="'partials/realm-menu.html'"></aside>
<div id="actions-bg"></div>
<div id="container-right" class="span9">
<a class="btn btn-small pull-right" href="#/create/user/{{realm.id}}">Add User</a>
<h1>
<span class="gray">{{realm.name}}</span> users
</h1>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Username</th>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tr data-ng-repeat="user in users">
<td><a href="#/realms/{{realm.id}}/users/{{user.userId}}">{{user.userId}}</a></td>
<td>{{user.firstName}}</td>
<td>{{user.lastName}}</td>
<td>{{user.email}}</td>
</tr>
</table>
</div>
<div id="container-right-bg"></div>
</div>
</div>

View file

@ -0,0 +1,35 @@
* {
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: "Open Sans", sans-serif;
}
body {
min-width: 120em;
height: 100%;
width: 100%;
font-family: "Open Sans", sans-serif;
}
body {
font-size: 62.5%;
}
h1, h2, h3, h4, h5, h6 {
letter-spacing: -0.1em;
font-weight: normal;
font-family: "Overpass", sans-serif;
}
a {
color: #0099d3;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}

View file

@ -0,0 +1,321 @@
/* General styles */
.btn-pressed {
box-shadow: none;
margin-top: 0.1em;
margin-left: 0;
margin-bottom: -0.1em;
margin-right: 0.1em;
}
a {
color: #07a1a3;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
input[type="submit"] {
cursor: pointer;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
strong {
font-weight: bold;
}
span.required {
color: #cb2915;
}
.hidden-element {
display: none;
}
/* */
.register-login {
background: url(images/register-login-bg.png) repeat left top;
margin: 0 auto;
font-size: 62.5%;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #777777;
}
.register-login .container {
width: 68em;
margin: 0 auto;
}
.register-login .header {
margin-top: 7.5em;
margin-left: 4em;
margin-right: 4em;
margin-bottom: 2.5em;
width: 60em;
}
.register-login h1 {
font-size: 4em;
font-weight: normal;
color: #c4c4c4;
letter-spacing: -0.02em;
float: left;
}
.register-login .back {
float: right;
font-size: 1.4em;
margin-top: 1.42857142857143em;
}
.feedback {
width: 60em;
margin-left: 2em;
padding: 1.5em 2em;
clear: both;
}
.feedback p {
font-size: 1.6em;
}
.feedback-error {
background-color: #ffe7e3;
border-left: 5px solid #cb2915;
margin-bottom: -15px;
z-index: 10;
position: relative;
}
.feedback-error p {
color: #cb2915;
}
.register-login-container {
background-color: #fff;
width: 100%;
}
.register-login-container form {
padding: 5em 4em 2.2em;
}
p.subtitle {
float: right;
margin-top: -2.14285714285714em;
font-size: 1.4em;
color: #b7b7b7;
}
label {
font-size: 1.8em;
width: 8.88888888888889em;
text-align: right;
display: inline-block;
position: relative;
}
label .required {
position: absolute;
right: -0.94444444444444em;
}
input[type="text"],
input[type="email"],
input[type="password"],
select,
textarea {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
border: 1px solid #dddddd;
box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.1);
transition: border 0.5s linear 0s, box-shadow 0.5s linear 0s;
color: #333333;
}
input[type="text"]:focus,
input[type="email"]:focus,
input[type="password"]:focus,
select:focus,
textarea:focus {
border-color: #07a1a3;
box-shadow: 0 0 5px rgba(7, 161, 163, 0.5);
}
input[type="text"].error,
input[type="email"].error,
input[type="password"].error,
select.error,
textarea.error {
border-color: #cb2915;
box-shadow: 0 0 5px rgba(203, 41, 21, 0.5);
background-color: rgba(203, 41, 21, 0.05);
}
label + input {
font-size: 2em;
height: 2em;
margin-left: 1.35em;
padding: 0 0.5em;
}
.register-login label + input {
width: 14em;
}
.register-login form > div {
margin-bottom: 2.5em;
}
.register-login .form-actions {
margin-left: 19em;
}
.form-actions .btn {
float: left;
}
.form-actions a {
font-size: 1.4em;
float: left;
margin-left: 1.07142857142857em;
color: #999999;
margin-top: 1em;
}
.btn {
font-size: 2em;
text-transform: uppercase;
letter-spacing: -0.05em;
padding: 0 1.1em;
height: 2em;
line-height: 2em;
border: none;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.btn-primary {
background-color: #07a1a3;
color: #fff;
box-shadow: -2px 2px 0 #077576;
margin-left: 0.1em;
}
.btn-primary:hover,
.btn-primary:focus {
background-color: #068e90;
}
.btn-primary:active {
box-shadow: none;
margin-top: 0.1em;
margin-left: 0;
margin-bottom: -0.1em;
margin-right: 0.1em;
background-color: #077576;
}
.bottom-actions {
background-color: rgba(221, 221, 221, 0.7);
padding: 2em 4em;
}
.bottom-actions p {
font-size: 1.4em;
}
/* Log in: social */
.social .login-container {
float: left;
width: 34em;
border-right: 1px solid rgba(221, 221, 221, 0.7);
}
.social form,
.social .bottom-actions {
clear: both;
}
.social form {
padding: 4em 4em 1.8em;
}
.social label {
display: block;
width: auto;
text-align: left;
margin-bottom: 0.55555555555556em;
line-height: 1em;
}
.social label + input {
margin-left: 0;
width: auto;
width: 11.8em;
}
.social .form-actions {
margin-left: 0;
}
.social-container {
width: 26em;
float: left;
margin-right: 4em;
margin-top: 4em;
padding-top: 2.8em;
padding-left: 3.9em;
}
.btn-social {
color: #fff;
display: block;
padding: 0;
line-height: 2em;
height: 2em;
margin-left: 0.1em;
letter-spacing: -0.025em;
}
.btn-social .icon {
display: block;
width: 2em;
border-right-width: 1px;
border-right-style: solid;
text-indent: -9999em;
float: left;
}
.btn-social .text {
font-size: 0.8em;
text-align: center;
display: block;
}
.btn-social:hover {
text-decoration: none;
}
.btn-social.facebook {
background-color: #3c5a99;
box-shadow: -2px 2px 0 #293e6b;
}
.btn-social.facebook:hover,
.btn-social.facebook:focus {
background-color: #36518a;
}
.btn-social.facebook:active {
box-shadow: none;
margin-top: 0.1em;
margin-left: 0;
margin-bottom: -0.1em;
margin-right: 0.1em;
background-color: #293e6b;
margin-top: 0;
border-top: 2px solid #fff;
}
.btn-social.facebook .icon {
border-color: #293e6b;
background-image: url(images/btn-social-fb.svg);
background-size: 2em;
background-repeat: no-repeat;
background-position: center 0.1em;
}
/* Specific social logins */
.social-two-three li {
margin-bottom: 5.5em;
}
.social-four {
padding-top: 1em;
}
.social-four li {
margin-bottom: 3.5em;
}
.social-five-nine {
padding-top: 0;
}
.social-five-nine h2 {
font-size: 1.8em;
margin-bottom: 1.11111111111112em;
}
.social-five-nine li {
margin-right: 2.5em;
margin-bottom: 2.5em;
float: left;
}
.social-five-nine li:nth-child(3),
.social-five-nine li:nth-child(6),
.social-five-nine li:nth-child(9) {
margin-right: 0;
}
.social-five-nine .btn-social {
height: 2.9em;
width: 3.4em;
line-height: 0.85em;
letter-spacing: -0.0125em;
}
.social-five-nine .btn-social .icon {
display: block;
width: 3.4em;
height: 2em;
border-right-width: 0;
border-bottom-width: 1px;
border-bottom-style: solid;
float: none;
}
.social-five-nine .btn-social .text {
font-size: 0.5em;
}

View file

@ -0,0 +1,393 @@
/* General styles */
@blue-green: #07a1a3;
@blue-green-darker: #077576;
@light-gray: #ddd;
@gray: #777;
@black: #333;
@red: #cb2915;
@font: "Helvetica Neue", Helvetica, Arial, sans-serif;
.btn-pressed {
box-shadow: none;
margin-top: 0.1em;
margin-left: 0;
margin-bottom: -0.1em;
margin-right: 0.1em;
}
a {
color: @blue-green;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
input[type="submit"] {
cursor: pointer;
font-family: @font;
}
strong {
font-weight: bold;
}
span.required {
color: @red;
}
.hidden-element {
display: none;
}
/* */
.register-login {
background: url(images/register-login-bg.png) repeat left top;
margin: 0 auto;
font-size: 62.5%;
font-family: @font;
color: @gray;
.container {
width: 68em;
margin: 0 auto;
}
.header {
margin-top: 7.5em;
margin-left: 4em;
margin-right: 4em;
margin-bottom: 2.5em;
width: 60em;
}
h1 {
font-size: 4em;
font-weight: normal;
color: darken(@light-gray, 10%);
letter-spacing: -0.02em;
float: left;
}
.back {
float: right;
font-size: 1.4em;
margin-top: 1.42857142857143em;
}
}
.feedback {
width: 60em;
margin-left: 2em;
padding: 1.5em 2em;
clear: both;
p {
font-size: 1.6em;
}
}
.feedback-error {
background-color: #ffe7e3;
border-left: 5px solid @red;
margin-bottom: -15px;
z-index: 10;
position: relative;
p {
color: @red;
}
}
.register-login-container {
background-color: #fff;
width: 100%;
form {
padding: 5em 4em 2.2em;
}
}
p.subtitle {
float: right;
margin-top: -2.14285714285714em;
font-size: 1.4em;
color: darken(@light-gray, 15%);
}
label {
font-size: 1.8em;
width: 8.88888888888889em;
text-align: right;
display: inline-block;
position: relative;
.required {
position: absolute;
right: -0.94444444444444em;
}
}
input[type="text"],
input[type="email"],
input[type="password"],
select,
textarea {
font-family: @font;
border: 1px solid @light-gray;
box-shadow: inset 0 2px 5px fade(#000, 10%);
transition: border 0.5s linear 0s, box-shadow 0.5s linear 0s;
color: @black;
&:focus {
border-color: @blue-green;
box-shadow: 0 0 5px fade(@blue-green, 50%);
}
&.error {
border-color: @red;
box-shadow: 0 0 5px fade(@red, 50%);
background-color: fade(@red, 5%);
}
}
label + input {
font-size: 2em;
height: 2em;
margin-left: 1.35em;
padding: 0 0.5em;
}
.register-login {
label + input {
width: 14em;
}
form > div {
margin-bottom: 2.5em;
}
.form-actions {
margin-left: 19em;
}
}
.form-actions {
.btn {
float: left;
}
a {
font-size: 1.4em;
float: left;
margin-left: 1.07142857142857em;
color: (@gray + #222);
margin-top: 1em;
}
}
.btn {
font-size: 2em;
text-transform: uppercase;
letter-spacing: -0.05em;
padding: 0 1.1em;
height: 2em;
line-height: 2em;
border: none;
font-family: @font;
}
.btn-primary {
background-color: @blue-green;
color: #fff;
box-shadow: -2px 2px 0 @blue-green-darker;
margin-left: 0.1em;
&:hover,
&:focus {
background-color: #068e90;
}
&:active {
.btn-pressed;
background-color: @blue-green-darker;
}
}
.bottom-actions {
background-color: fade(@light-gray, 70%);
padding: 2em 4em;
p {
font-size: 1.4em;
}
}
/* Log in: social */
.social {
.login-container {
float: left;
width: 34em;
border-right: 1px solid fade(@light-gray, 70%);
}
form,
.bottom-actions {
clear: both;
}
form {
padding: 4em 4em 1.8em;
}
label {
display: block;
width: auto;
text-align: left;
margin-bottom: 0.55555555555556em;
line-height: 1em;
}
label + input {
margin-left: 0;
width: auto;
width: 11.8em;
}
.form-actions {
margin-left: 0;
}
}
.social-container {
width: 26em;
float: left;
margin-right: 4em;
margin-top: 4em;
padding-top: 2.8em;
padding-left: 3.9em;
}
.btn-social {
color: #fff;
display: block;
padding: 0;
line-height: 2em;
height: 2em;
margin-left: 0.1em;
letter-spacing: -0.025em;
.icon {
display: block;
width: 2em;
border-right-width: 1px;
border-right-style: solid;
text-indent: -9999em;
float: left;
}
.text {
font-size: 0.8em;
text-align: center;
display: block;
}
&:hover {
text-decoration: none;
}
}
.btn-social.facebook {
background-color: #3c5a99;
box-shadow: -2px 2px 0 #293e6b;
&:hover,
&:focus {
background-color: #36518a;
}
&:active {
.btn-pressed;
background-color: #293e6b;
margin-top: 0;
border-top: 2px solid #fff;
}
.icon {
border-color: #293e6b;
background-image: url(images/btn-social-fb.svg);
background-size: 2em;
background-repeat: no-repeat;
background-position: center 0.1em;
}
}
/* Specific social logins */
.social-two-three li {
margin-bottom: 5.5em;
}
.social-four {
padding-top: 1em;
li {
margin-bottom: 3.5em;
}
}
.social-five-nine {
padding-top: 0;
h2 {
font-size: 1.8em;
margin-bottom: 1.11111111111112em;
}
li {
margin-right: 2.5em;
margin-bottom: 2.5em;
float: left;
}
li:nth-child(3),
li:nth-child(6),
li:nth-child(9) {
margin-right: 0;
}
.btn-social {
height: 2.9em;
width: 3.4em;
line-height: 0.85em;
letter-spacing: -0.0125em;
.icon {
display: block;
width: 3.4em;
height: 2em;
border-right-width: 0;
border-bottom-width: 1px;
border-bottom-style: solid;
float: none;
}
.text {
font-size: 0.5em;
}
}
}

View file

@ -0,0 +1,61 @@
fieldset {
border: none;
}
input[type="text"],
input[type="password"],
input[type="email"] {
font-size: 1.1em;
padding: 0 0.545454545454545em;
min-width: 18.1818181818182em;
height: 2.18181818181818em;
border: 1px #b6b6b6 solid;
border-radius: 2px;
box-shadow: inset 0px 2px 2px rgba(0, 0, 0, 0.1);
color: #333;
}
input[type="text"]:hover,
input[type="password"]:hover,
input[type="email"]:hover {
border-color: #62afdb;
}
input[type="text"]:focus,
input[type="password"]:focus,
input[type="email"]:focus {
border-color: #62afdb;
box-shadow: #62afdb 0 0 5px;
}
input[type="button"],
input[type="submit"]{
font-size: 1.3em;
padding: 0.30769230769231em 1.07692307692308em;
border: 1px #21799e solid;
border-radius: 2px;
background-image: linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -o-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -moz-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -webkit-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -ms-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #00a9ec), color-stop(1, 0, #009bd3));
color: #fff;
font-weight: bold;
letter-spacing: 0.04em;
}
input[type="button"]:hover,
input[type="button"]:focus,
input[type="submit"]:hover,
input[type="submit"]:focus
{
background-color: #009BD3;
background-image: none;
cursor: pointer;
}
input[type="button"]:active,
input[type="submit"]:active {
background-color: #0099d4;
background-image: none;
cursor: pointer;
box-shadow: inset 0 0 5px 3px #0074ae;
}
input[type="checkbox"] {
margin-right: 0.5em;
}

View file

@ -0,0 +1,66 @@
fieldset {
border: none;
}
input[type="text"],
input[type="password"],
input[type="email"] {
font-size: 1.1em;
padding: 0 0.545454545454545em;
min-width: 18.1818181818182em;
height: 2.18181818181818em;
border: 1px #b6b6b6 solid;
border-radius: 2px;
box-shadow: inset 0px 2px 2px rgba(0,0,0,0.1);
color: #333;
&:hover {
border-color: #62afdb;
}
&:focus {
border-color: #62afdb;
box-shadow: #62afdb 0 0 5px;
}
}
input[type="button"] {
font-size: 1.3em;
padding: 0.30769230769231em 1.07692307692308em;
border: 1px #21799e solid;
border-radius: 2px;
background-image: linear-gradient(top, #00A9EC 0%, #009BD3 100%);
background-image: -o-linear-gradient(top, #00A9EC 0%, #009BD3 100%);
background-image: -moz-linear-gradient(top, #00A9EC 0%, #009BD3 100%);
background-image: -webkit-linear-gradient(top, #00A9EC 0%, #009BD3 100%);
background-image: -ms-linear-gradient(top, #00A9EC 0%, #009BD3 100%);
background-image: -webkit-gradient(
linear,
left top,
left bottom,
color-stop(0.0, #00A9EC),
color-stop(1,0, #009BD3)
);
color: #fff;
font-weight: bold;
letter-spacing: 0.04em;
&:hover,
&:focus {
background-color: #009BD3;
background-image: none;
cursor: pointer;
}
&:active {
background-color: #0099d4;
background-image: none;
cursor: pointer;
box-shadow: inset 0 0 5px 3px #0074ae;
}
}
input[type="checkbox"] {
margin-right: 0.5em;
}

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="80px" height="76px" viewBox="0 0 80 76" enable-background="new 0 0 80 76" xml:space="preserve">
<path id="f" fill="#FFFFFF" d="M43.717,62V40.104h7.35l1.1-8.533h-8.449v-5.448c0-2.471,0.686-4.154,4.229-4.154l4.518-0.002v-7.632
C51.682,14.231,49,14,45.88,14c-6.514,0-10.975,3.977-10.975,11.279v6.292h-7.368v8.533h7.368V62H43.717z"/>
</svg>

After

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View file

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="1680px" height="1080px" viewBox="0 0 1680 1080" enable-background="new 0 0 1680 1080" xml:space="preserve">
<rect fill="#383D42" width="1680" height="1080"/>
<g>
<defs>
<filter id="Adobe_OpacityMaskFilter" filterUnits="userSpaceOnUse" x="1057" y="597" width="704" height="572">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="1057" y="597" width="704" height="572" id="SVGID_1_">
<g filter="url(#Adobe_OpacityMaskFilter)">
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="1302.4395" y1="-269.9951" x2="1622.4397" y2="22.0046" gradientTransform="matrix(-1 0 0 -1 3112 976.6914)">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<rect x="1035" y="573" fill="url(#SVGID_2_)" width="752" height="620"/>
</g>
</mask>
<path mask="url(#SVGID_1_)" fill="#D8D8D8" d="M1761,597c-140,214-410,510-704,572h704V597z"/>
<defs>
<filter id="Adobe_OpacityMaskFilter_1_" filterUnits="userSpaceOnUse" x="1056.742" y="596.315" width="705.304" height="573.907">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="1056.742" y="596.315" width="705.304" height="573.907" id="SVGID_3_">
<g filter="url(#Adobe_OpacityMaskFilter_1_)">
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="1302.4395" y1="-269.9951" x2="1622.4397" y2="22.0046" gradientTransform="matrix(-1 0 0 -1 3112 976.6914)">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<rect x="1035" y="573" fill="url(#SVGID_4_)" width="752" height="620"/>
</g>
</mask>
<path opacity="0.1" mask="url(#SVGID_3_)" fill="none" stroke="#D8D8D8" stroke-width="2.5" stroke-miterlimit="10" d="M1761,597
c-140,214-410,510-704,572"/>
</g>
<defs>
<filter id="Adobe_OpacityMaskFilter_2_" filterUnits="userSpaceOnUse" x="168.747" y="365.576" width="1798.615" height="822.631">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="168.747" y="365.576" width="1798.615" height="822.631" id="SVGID_5_">
<g filter="url(#Adobe_OpacityMaskFilter_2_)">
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="1476.5908" y1="477.5732" x2="2688.6016" y2="21.5689" gradientTransform="matrix(-0.9876 -0.1569 0.1569 -0.9876 3048.3154 1294.3018)">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<polygon fill="url(#SVGID_6_)" points="329.208,58.782 1976.554,320.459 1810.26,1367.334 162.914,1105.656 "/>
</g>
</mask>
<path mask="url(#SVGID_5_)" fill="#E0E0E0" d="M1967.361,365.576c-393.429,322.269-1126.777,782.925-1798.615,728.856
c379.652,70.433,1428.387,135.769,1651.069,59.762L1967.361,365.576z"/>
<path fill="#D8D8D8" d="M-114.695,1221h1160.347c80.272-27.337,158.024-70.67,230.989-123.266
C792.789,983.34-203.837,592.187-368.695,373L-114.695,1221z"/>
<defs>
<filter id="Adobe_OpacityMaskFilter_3_" filterUnits="userSpaceOnUse" x="-395" y="514.337" width="1423.831" height="829.326">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="-395" y="514.337" width="1423.831" height="829.326" id="SVGID_7_">
<g filter="url(#Adobe_OpacityMaskFilter_3_)">
<linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="2111.374" y1="319.9775" x2="3115.3701" y2="81.9786" gradientTransform="matrix(-1.075 0.1117 -0.1167 -1.1224 3229.8789 866.1523)">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="0.0972" style="stop-color:#060606"/>
<stop offset="0.2213" style="stop-color:#151515"/>
<stop offset="0.36" style="stop-color:#303030"/>
<stop offset="0.5093" style="stop-color:#545454"/>
<stop offset="0.6671" style="stop-color:#838383"/>
<stop offset="0.8323" style="stop-color:#BDBDBD"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<polygon fill="url(#SVGID_8_)" points="-543.126,587.599 1129.521,413.746 1223.549,1318.382 -449.1,1492.233 "/>
</g>
</mask>
<path mask="url(#SVGID_7_)" fill="#C6C6C5" d="M-395,1343.663c225.178-156.636,836.847-511.283,1423.831-382.832l-17.056-446.355
C360.896,503.847-136.975,1108.097-395,1343.663z"/>
<path opacity="0.2" fill="none" stroke="#D8D8D8" stroke-width="5" stroke-miterlimit="10" d="M-368.695,373
c164.858,219.187,1161.484,610.34,1645.336,724.734c154.24,39.423,293.768,67.189,413.359,86.745"/>
<path opacity="0.4" fill="none" stroke="#777D82" stroke-width="3" stroke-miterlimit="10" d="M-218.695,311
c338,316,1048,836,1440,990"/>
<path opacity="0.1" fill="none" stroke="#C6C6C5" stroke-width="2" stroke-miterlimit="10" d="M1257.069,1089.063
c124.494-56.997,382.481-291.736,437.979-414.73"/>
<defs>
<filter id="Adobe_OpacityMaskFilter_4_" filterUnits="userSpaceOnUse" x="535.169" y="-135" width="1423.831" height="829.326">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="535.169" y="-135" width="1423.831" height="829.326" id="SVGID_9_">
<g filter="url(#Adobe_OpacityMaskFilter_4_)">
<linearGradient id="SVGID_10_" gradientUnits="userSpaceOnUse" x1="664.5693" y1="382.668" x2="1668.5647" y2="144.6692" gradientTransform="matrix(1.075 -0.1117 0.1167 1.1224 -117.8789 110.5386)">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<polygon fill="url(#SVGID_10_)" points="2107.126,621.064 434.478,794.917 340.452,-109.719 2013.1,-283.57 "/>
</g>
</mask>
<path mask="url(#SVGID_9_)" fill="#C6C6C5" d="M1959-135C1733.822,21.636,1122.153,376.284,535.169,247.832l17.055,446.356
C1203.104,704.816,1700.975,100.567,1959-135z"/>
<path fill="#D8D8D8" d="M1743-27H582.653C502.38,0.337,424.629,43.67,351.665,96.265C835.516,210.66,1832.142,601.813,1997,821
L1743-27z"/>
<defs>
<filter id="Adobe_OpacityMaskFilter_5_" filterUnits="userSpaceOnUse" x="-49" y="-47" width="704" height="572">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="-49" y="-47" width="704" height="572" id="SVGID_11_">
<g filter="url(#Adobe_OpacityMaskFilter_5_)">
<linearGradient id="SVGID_12_" gradientUnits="userSpaceOnUse" x1="-97.5605" y1="-124.686" x2="222.4397" y2="167.3137">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<rect x="-75" y="-71" fill="url(#SVGID_12_)" width="752" height="620"/>
</g>
</mask>
<path mask="url(#SVGID_11_)" fill="#D8D8D8" d="M-49,525C91,311,361,15,655-47H-49V525z"/>
<defs>
<filter id="Adobe_OpacityMaskFilter_6_" filterUnits="userSpaceOnUse" x="-209" y="-147.691" width="1662" height="1002.691">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="-209" y="-147.691" width="1662" height="1002.691" id="SVGID_13_">
<g filter="url(#Adobe_OpacityMaskFilter_6_)">
<linearGradient id="SVGID_14_" gradientUnits="userSpaceOnUse" x1="54.2939" y1="584.9688" x2="1266.2927" y2="128.9689">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<rect x="-211" y="-159" fill="url(#SVGID_14_)" width="1668" height="1060"/>
</g>
</mask>
<path mask="url(#SVGID_13_)" fill="#E0E0E0" d="M-209,855C129,475,781-95,1453-147C1067-157,21-57-187,53L-209,855z"/>
<path opacity="0.2" fill="none" stroke="#D8D8D8" stroke-width="5" stroke-miterlimit="10" d="M1997,821
C1832.142,601.813,835.516,210.66,351.665,96.265C197.423,56.843,57.896,29.076-61.695,9.521"/>
<path opacity="0.4" fill="none" stroke="#777D82" stroke-width="3" stroke-miterlimit="10" d="M1847,883C1509,567,799,47,407-107"/>
<defs>
<filter id="Adobe_OpacityMaskFilter_7_" filterUnits="userSpaceOnUse" x="-50.046" y="-48.223" width="705.304" height="573.907">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="-50.046" y="-48.223" width="705.304" height="573.907" id="SVGID_15_">
<g filter="url(#Adobe_OpacityMaskFilter_7_)">
<linearGradient id="SVGID_16_" gradientUnits="userSpaceOnUse" x1="-97.5605" y1="-124.686" x2="222.4397" y2="167.3137">
<stop offset="0" style="stop-color:#000000"/>
<stop offset="1" style="stop-color:#FFFFFF"/>
</linearGradient>
<rect x="-75" y="-71" fill="url(#SVGID_16_)" width="752" height="620"/>
</g>
</mask>
<path opacity="0.1" mask="url(#SVGID_15_)" fill="none" stroke="#D8D8D8" stroke-width="2.5" stroke-miterlimit="10" d="M-49,525
C91,311,361,15,655-47"/>
<circle fill="#D8D8D8" cx="1247.084" cy="399.5" r="2.5"/>
<circle fill="#D8D8D8" cx="436.333" cy="117.667" r="2"/>
<circle fill="#D8D8D8" cx="254.667" cy="173.667" r="2"/>
<circle fill="#D8D8D8" cx="375" cy="101.667" r="4"/>
<circle fill="#D8D8D8" cx="351.665" cy="96.265" r="5"/>
</svg>

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="1px" height="400px" viewBox="0 0 1 400" enable-background="new 0 0 1 400" xml:space="preserve">
<rect opacity="0.15" fill="#FFFFFF" width="1.447" height="400"/>
</svg>

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="324px" height="400px" viewBox="0 0 324 400" enable-background="new 0 0 324 400" xml:space="preserve">
<rect x="6.001" opacity="0.07" fill="#FFFFFF" width="0.997" height="190"/>
<rect x="6" y="209" opacity="0.07" fill="#FFFFFF" width="1" height="191"/>
<rect x="323" opacity="0.15" fill="#FFFFFF" width="1.447" height="400"/>
<g opacity="0.15">
<path fill="#FFFFFF" d="M6.501,200.066c0,1.047-0.264,1.864-0.791,2.452S4.454,203.4,3.524,203.4c-0.574,0-1.084-0.135-1.529-0.404
s-0.789-0.656-1.031-1.16s-0.363-1.094-0.363-1.77c0-1.047,0.262-1.862,0.785-2.446s1.25-0.876,2.18-0.876
c0.898,0,1.612,0.299,2.142,0.896S6.501,199.047,6.501,200.066z M1.608,200.066c0,0.82,0.164,1.445,0.492,1.875
s0.811,0.645,1.447,0.645s1.12-0.214,1.45-0.642s0.495-1.054,0.495-1.878c0-0.816-0.165-1.437-0.495-1.86s-0.817-0.636-1.462-0.636
c-0.637,0-1.117,0.209-1.441,0.627S1.608,199.238,1.608,200.066z"/>
<path fill="#FFFFFF" d="M11.136,196.744c0.285,0,0.541,0.023,0.768,0.07l-0.135,0.902c-0.266-0.059-0.5-0.088-0.703-0.088
c-0.52,0-0.964,0.211-1.333,0.633s-0.554,0.947-0.554,1.576v3.445H8.206v-6.422h0.803l0.111,1.189h0.047
c0.238-0.418,0.525-0.74,0.861-0.967S10.733,196.744,11.136,196.744z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,268 @@
body {
min-height: 60em;
}
.rcue-login-register {
background-color: #1D2226;
background-image: url("img/login-screen-background.jpg");
background-position: top left;
background-size: auto;
background-repeat: no-repeat;
color: #fff;
/* Login area */
/* Social login area */
/* Info area */
}
.rcue-login-register h1 a {
position: absolute;
top: 5em;
right: 6.4em;
}
.rcue-login-register .content {
position: absolute;
bottom: 15%;
width: 100%;
min-width: 76em;
}
.rcue-login-register h2 {
padding-left: 4.34782608695652em;
/* 100px */
font-family: "Overpass", sans-serif;
font-size: 2.3em;
font-weight: 100;
text-transform: uppercase;
letter-spacing: 0.005em;
}
.rcue-login-register h2 strong {
font-weight: bold;
}
.rcue-login-register .background-area {
border-top: 0.1em rgba(255, 255, 255, 0.05) solid;
border-bottom: 0.1em rgba(255, 255, 255, 0.05) solid;
background-color: rgba(0, 0, 0, 0.3);
padding: 3em 0 3em 10em;
margin-top: 2.7em;
width: 100%;
min-width: 120em;
}
.rcue-login-register .background-area section {
float: left;
padding: 1.5em 4.5em 1.5em 4.6em;
width: auto;
position: relative;
}
.rcue-login-register .background-area section h3 {
display: none;
}
.rcue-login-register .background-area section:first-child {
padding-right: 4.5em;
}
.rcue-login-register .form-area {
background-image: url(img/login-register-separator.svg);
background-repeat: no-repeat;
background-position: 40.2em center;
}
.rcue-login-register .form-area.social {
background-image: url(img/login-register-social-separators.svg);
background-position: 39.6em center;
}
.rcue-login-register section.app-form {
padding-left: 0;
}
.rcue-login-register form > div {
margin-bottom: 1em;
}
.rcue-login-register label,
.rcue-login-register .social-login > p {
display: inline-block;
font-size: 1.4em;
font-weight: 400;
}
.rcue-login-register label {
width: 6.07142857142857em;
/* 85px */
}
.rcue-login-register label.two-lines {
float: left;
margin-top: -0.28571428571429em;
/* -4px */
line-height: 1.1em;
}
.rcue-login-register input[type="text"],
.rcue-login-register input[type="password"] {
width: 24.7272727272727em;
/* 272px */
}
.rcue-login-register form > div.aside-btn {
float: left;
font-size: 1.1em;
margin-left: 7.72727272727273em;
/* 85px */
margin-top: 0.90909090909091em;
/* 10px */
margin-bottom: 0;
}
.rcue-login-register form > div.aside-btn label {
font-size: 1em;
width: auto;
}
.rcue-login-register form > div.aside-btn input[type="checkbox"] {
margin-bottom: 0.54545454545455em;
/* 6px */
}
.rcue-login-register form > input[type="button"] {
float: right;
margin-top: 0.76923076923077em;
/* 10px */
}
.rcue-login-register p.subtitle {
font-size: 1.1em;
color: #999;
position: absolute;
right: 4.09090909090909em;
top: -0.636363636363636em;
}
.rcue-login-register section.social-login > span {
display: none;
}
.rcue-login-register section.social-login > p {
float: left;
margin-top: 0.28571428571429em;
/* 14px */
width: 6.78571428571429em;
/* 95px */
}
.rcue-login-register section.social-login > ul {
float: left;
}
.rcue-login-register section.social-login li {
margin-bottom: 2em;
}
.rcue-login-register section.social-login li:last-child {
margin-bottom: 0;
}
.rcue-login-register section.info-area {
padding-right: 0;
}
.rcue-login-register section.info-area p,
.rcue-login-register section.info-area li {
font-size: 1.4em;
margin-bottom: 1.64285714285714em;
/* 23px */
}
.rcue-login-register section.info-area li {
color: #999;
margin-bottom: 1em;
}
.rcue-login-register section.info-area li:last-child {
margin-bottom: 0;
}
@media screen and (min-width: 1280px) {
.rcue-login-register {
background-size: 100% auto;
}
}
/* Social buttons */
.zocial,
a.zocial {
padding: 0;
line-height: 2.3em;
height: 2.3em;
width: 131px;
border-radius: 2px;
box-shadow: none;
background-image: none;
text-shadow: none;
}
.zocial .text,
a.zocial .text {
font-size: 1.2em;
line-height: 1.25em;
text-align: center;
display: block;
font-family: "Open Sans", sans-serif;
font-weight: normal;
border-left: 1px solid rgba(0, 0, 0, 0.15);
margin-left: 3em;
/* 36 px */
margin-top: 0.25em;
/* 3px */
}
.zocial:hover,
a.zocial:hover,
.zocial:active,
a.zocial:active,
.zocial:focus,
a.zocial:focus {
text-decoration: none;
background-image: none;
}
.zocial:hover,
a.zocial:hover {
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);
}
.zocial:before,
a.zocial:before {
margin: 0;
padding: 0;
box-shadow: none;
border: none;
width: 3em;
/* 36px */
}
.zocial.facebook:before {
width: 2.66666666666667em;
/* 32px */
}
/* Register page */
.rcue-login-register.register label {
width: 7.5em;
/* 105px */
}
.rcue-login-register.register input[type="text"],
.rcue-login-register.register input[type="email"],
.rcue-login-register.register input[type="password"] {
width: 22.9090909090909em;
/* 252px */
}
.rcue-login-register.register form > div.aside-btn {
margin-left: 9.54545454545454em;
/* 105px */
width: 12.5454545454546em;
/* 138px */
}
.rcue-login-register.register form > div.aside-btn p {
line-height: 1.3em;
}
/* Customer login */
.rcue-login-register.customer {
background-image: url("img/customer-login-screen-bg2.jpg");
}
.rcue-login-register.customer h2 {
display: inline-block;
}
.rcue-login-register.customer p.powered {
display: inline-block;
font-size: 1.3em;
margin-left: 1.2em;
}

View file

@ -0,0 +1,302 @@
body {
min-height: 60em;
}
.rcue-login-register {
background-color: #1D2226;
background-image: url("img/login-screen-background.jpg");
background-position: top left;
background-size: auto;
background-repeat: no-repeat;
color: #fff;
h1 a {
position: absolute;
top: 5em;
right: 6.4em;
}
.content {
position: absolute;
bottom: 15%;
width: 100%;
min-width: 76em;
}
h2 {
padding-left: 4.34782608695652em; /* 100px */
font-family: "Overpass", sans-serif;
font-size: 2.3em;
font-weight: 100;
text-transform: uppercase;
letter-spacing: 0.005em;
strong {
font-weight: bold;
}
}
.background-area {
border-top: 0.1em rgba(255, 255, 255, 0.05) solid;
border-bottom: 0.1em rgba(255, 255, 255, 0.05) solid;
background-color: rgba(0, 0, 0, 0.3);
padding: 3em 0 3em 10em;
margin-top: 2.7em;
width: 100%;
min-width: 120em;
section {
float: left;
padding: 1.5em 4.5em 1.5em 4.6em;
width: auto;
position: relative;
h3 {
display: none;
}
&:first-child {
padding-right: 4.5em;
}
}
}
.form-area {
background-image: url(img/login-register-separator.svg);
background-repeat: no-repeat;
background-position: 40.2em center;
}
.form-area.social {
background-image: url(img/login-register-social-separators.svg);
background-position: 39.6em center;
}
/* Login area */
section.app-form {
padding-left: 0;
}
form > div {
margin-bottom: 1em;
}
label,
.social-login > p {
display: inline-block;
font-size: 1.4em;
font-weight: 400;
}
label {
width: 6.07142857142857em; /* 85px */
}
label.two-lines {
float: left;
margin-top: -0.28571428571429em; /* -4px */
line-height: 1.1em;
}
input[type="text"],
input[type="password"] {
width: 24.7272727272727em; /* 272px */
}
form > div.aside-btn {
float: left;
font-size: 1.1em;
margin-left: 7.72727272727273em; /* 85px */
margin-top: 0.90909090909091em; /* 10px */
margin-bottom: 0;
label {
font-size: 1em;
width: auto;
}
input[type="checkbox"] {
margin-bottom: 0.54545454545455em; /* 6px */
}
}
form > input[type="button"] {
float: right;
margin-top: 0.76923076923077em; /* 10px */
}
p.subtitle {
font-size: 1.1em;
color: #999;
position: absolute;
right: 4.09090909090909em;
top: -0.636363636363636em;
}
/* Social login area */
section.social-login {
> span {
display: none;
}
> p {
float: left;
margin-top: 0.28571428571429em; /* 14px */
width: 6.78571428571429em; /* 95px */
}
> ul {
float: left;
}
li {
margin-bottom: 2em;
&:last-child {
margin-bottom: 0;
}
}
}
/* Info area */
section.info-area {
padding-right: 0;
p,
li {
font-size: 1.4em;
margin-bottom: 1.64285714285714em; /* 23px */
}
li {
color: #999;
margin-bottom: 1em;
}
li:last-child {
margin-bottom: 0;
}
}
}
@media screen and (min-width: 1280px) {
.rcue-login-register {
background-size: 100% auto;
}
}
/* Social buttons */
.zocial,
a.zocial {
padding: 0;
line-height: 2.3em;
height: 2.3em;
width: 131px;
border-radius: 2px;
box-shadow: none;
background-image: none;
text-shadow: none;
.text {
font-size: 1.2em;
line-height: 1.25em;
text-align: center;
display: block;
font-family: "Open Sans", sans-serif;
font-weight: normal;
border-left: 1px solid rgba(0, 0, 0, 0.15);
margin-left: 3em; /* 36 px */
margin-top: 0.25em; /* 3px */
}
&:hover,
&:active,
&:focus {
text-decoration: none;
background-image: none;
}
&:hover {
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);
}
&:before {
margin: 0;
padding: 0;
box-shadow: none;
border: none;
width: 3em; /* 36px */
}
}
.zocial.facebook:before {
width: 2.66666666666667em; /* 32px */
}
/* Register page */
.rcue-login-register.register {
label {
width: 7.5em; /* 105px */
}
input[type="text"],
input[type="email"],
input[type="password"] {
width: 22.9090909090909em; /* 252px */
}
form > div.aside-btn {
margin-left: 9.54545454545454em; /* 105px */
width: 12.5454545454546em; /* 138px */
p {
line-height: 1.3em;
}
}
}
/* Customer login */
.rcue-login-register.customer {
background-image: url("img/customer-login-screen-bg2.jpg");
h2 {
display: inline-block;
}
p.powered {
display: inline-block;
font-size: 1.3em;
margin-left: 1.2em;
}
}

View file

@ -0,0 +1,71 @@
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/* Clearfix */
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
.clearfix {
display: inline-block;
}
html[xmlns] .clearfix {
display: block;
}
* html .clearfix {
height: 1%;
}

View file

@ -0,0 +1,151 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata></metadata>
<defs>
<font id="zocialregular" horiz-adv-x="1000" >
<font-face units-per-em="1000" ascent="804" descent="-196" />
<missing-glyph horiz-adv-x="250" />
<glyph unicode=" " horiz-adv-x="250" />
<glyph unicode="&#x09;" horiz-adv-x="250" />
<glyph unicode="&#xa0;" horiz-adv-x="250" />
<glyph unicode="!" d="M5 308q0 215 140.5 355.5t355.5 140.5t355.5 -140.5t140.5 -355.5q0 -182 -103 -313t-280 -171q-9 17 -33.5 52t-34.5 56q64 -26 86 -26q16 0 16 50q0 93 -17 93q-25 0 -97 -55q0 14 -15 12h-5q-26 69 -26 123q0 15 3 30q92 -45 148 -45q31 0 93.5 18t62.5 39 q0 13 -17 13q-26 0 -75 -7t-75 -7q-27 0 -59.5 14t-32.5 38q0 5 1.5 7.5t4.5 3t6 0t8 -1t9 -0.5q9 0 26 -2.5t25 -2.5q31 0 127 36.5t96 56.5q0 12 -18.5 17t-34.5 5q-14 0 -42 -7.5t-61 -18t-44 -13.5q4 20 4 32q0 47 -25 109.5t-58 92.5q-27 24 -72 33q-28 36 -87.5 65.5 t-105.5 29.5q-9 0 -27.5 -3.5t-23.5 -4.5l-22 -31l6 -1q7 0 21.5 2t21.5 2q34 0 78 -14q-28 -14 -49 -19q-2 -1 -13 -2.5t-18.5 -3t-14 -6t-6.5 -11.5q56 6 84 6q38 0 60 -7q-77 -9 -118.5 -53t-41.5 -121q0 -27 4 -50q19 -120 73 -358q33 -154 37 -170l1 -4 q-160 50 -251 185.5t-91 307.5zM288 432q0 -6 3 -12q-1 16 18 28t36 12q8 0 20 -5q-10 13 -29 13q-17 0 -32.5 -9.5t-15.5 -26.5zM321 357q0 13 10.5 23.5t23.5 10.5t23.5 -10.5t10.5 -23.5t-10.5 -23.5t-23.5 -10.5t-23.5 10.5t-10.5 23.5zM361 368q0 -8 9 -8t9 8q0 9 -9 9 t-9 -9zM529 455q8 13 37 13q13 0 33 -10q-10 22 -35 22q-31 0 -35 -25zM552 377q0 12 9 20.5t20 8.5q12 0 20.5 -8.5t8.5 -20.5q0 -11 -8.5 -20t-20.5 -9q-11 0 -20 9t-9 20zM587 387q0 -8 7 -8q8 0 8 8q0 7 -8 7q-7 0 -7 -7z" />
<glyph unicode="&#x22;" horiz-adv-x="1294" d="M0 402q0 105 52.5 188t136.5 131.5t180.5 73.5t194.5 25q29 0 43 -1q115 -6 226 -41q87 -28 166 -74.5t146.5 -109t108 -146.5t40.5 -176q0 -13 -1 -19q-11 -152 -120.5 -256t-268.5 -147q-107 -30 -229 -30h-8q-201 0 -315 53q-6 2 -7 6q0 2 3 2q1 0 3.5 -0.5t3.5 -0.5 q50 -12 89 -12q24 0 47 4.5t43.5 20t20.5 39.5q0 12 -6 24q-9 16 -58.5 33.5t-114 33.5t-75.5 20q-80 26 -139 66q0 1 3.5 9.5t6 14.5t7 12t8.5 6h179q9 0 16.5 -21.5t21 -43.5t35.5 -22q18 0 31 11.5t13 29.5q0 11 -84 199t-106 231q-6 15 -16 15q-8 0 -13 -9l-3 -6 q-8 -15 -52 -114l-107 -238l-7 -15q-95 109 -95 234zM218 236q0 10 54 129l5 3q6 0 32.5 -63.5t26.5 -69.5q0 -4 -5 -4h-108q-5 0 -5 5zM525 113q0 -45 47 -45t47 45v388q0 45 -47 45t-47 -45v-388zM710 113q0 -45 47 -45t47 45v181l92 -185q13 -29 41 -29q32 0 46 29 l91 185v-181q0 -45 47 -45q48 0 48 45v388q0 45 -47 45q-35 0 -47 -29l-138 -302l-133 302q-14 29 -48 29q-46 0 -46 -45v-388z" />
<glyph unicode="#" horiz-adv-x="1009" d="M0 -180v501h501v-501h-501zM509 319v501h500v-501h-500z" />
<glyph unicode="$" horiz-adv-x="974" d="M0 -72l194 891h438q50 0 96.5 -18t84.5 -55.5t52.5 -94.5t-0.5 -135q-29 -136 -128.5 -214t-233.5 -78h-183l-63 -296h-257zM100 -181h257l63 295h184q134 0 233 78t129 214q28 135 -43 219q33 -74 12 -170q-29 -136 -128.5 -214t-233.5 -78h-183l-63 -295h-216zM357 394 h83l42 183h125q2 0 17 -3q-8 29 -31.5 46.5t-55.5 17.5h-125zM482 395q48 2 89.5 37t52.5 84q0 2 1 6t1 6h-114z" />
<glyph unicode="%" horiz-adv-x="957" d="M0 -67v514q0 179 84.5 278t259.5 99h288h260q-5 -5 -52.5 -53t-100 -101t-109 -109.5t-95 -93t-41.5 -36.5q-15 0 -15 16v156h-48q-59 0 -94.5 -6.5t-63 -26t-39 -56.5t-11.5 -96v-262zM67 -184q5 5 52.5 53t100 101t109 109.5t95 93t41.5 36.5q15 0 15 -16v-156h48 q116 0 161.5 35.5t45.5 149.5v262l224 223v-514q0 -179 -84.5 -278t-259.5 -99h-288h-260z" />
<glyph unicode="&#x26;" horiz-adv-x="921" d="M0 221v269q0 26 19 44.5t44 18.5q26 0 44.5 -18.5t18.5 -44.5v-269q0 -26 -18.5 -44.5t-44.5 -18.5t-44.5 18.5t-18.5 44.5zM173 121v418h574v-418q0 -26 -18.5 -44.5t-44.5 -18.5h-448q-26 0 -44.5 18.5t-18.5 44.5zM173 586h574q0 115 -85 189t-202 74t-202 -74 t-85 -189zM274 902q0 8 7 8q3 0 7 -2l49 -89l-15 -8q-48 88 -48 91zM289 95q0 27 19 45t47 18q25 0 44 -19t19 -44v-202q0 -28 -19 -45.5t-47 -17.5q-26 0 -44.5 18.5t-18.5 44.5v202zM294 715q0 16 12 27.5t28 11.5t27.5 -11.5t11.5 -27.5q0 -17 -11.5 -28.5t-28.5 -11.5 q-16 0 -27.5 12t-11.5 28zM502 95q0 27 19.5 45t46.5 18q26 0 44.5 -18.5t18.5 -44.5v-202q0 -28 -19 -45.5t-47 -17.5q-26 0 -44.5 18.5t-18.5 44.5v202zM547 715q0 16 12 27.5t28 11.5t27.5 -11.5t11.5 -27.5q0 -17 -12 -28.5t-28 -11.5t-27.5 12t-11.5 28zM583 819 q2 3 14 28.5t23.5 44t18.5 18.5t7 -9v-2l-48 -89zM794 221v268q0 26 18.5 45t44.5 19t44.5 -19t18.5 -45v-268q0 -26 -18.5 -44.5t-44.5 -18.5t-45 18.5t-18 44.5z" />
<glyph unicode="'" horiz-adv-x="824" d="M0 322q0 107 29 202q28 92 83 159q56 67 135 102q81 36 178 36q128 0 217 -61q90 -59 136 -157q46 -95 46 -196q0 -93 -47 -120t-132 -27h-423q0 -85 30 -148q29 -65 76 -96q50 -33 106 -33q41 0 71 10q31 10 62 33q31 22 56 47t66 69q15 16 47 16q34 0 54 -21 q21 -21 21 -58q0 -32 -23 -78q-21 -43 -70 -85q-46 -41 -116 -68q-71 -27 -161 -27q-209 0 -325 135q-116 136 -116 366zM222 400h392q-7 125 -60 188q-51 62 -136 62q-82 0 -133 -63q-52 -63 -63 -187z" />
<glyph unicode="(" horiz-adv-x="571" d="M0 -73v786q0 44 31.5 75.5t75.5 31.5h357q44 0 75.5 -31.5t31.5 -75.5v-786q0 -44 -31.5 -75.5t-75.5 -31.5h-357q-44 0 -75.5 31.5t-31.5 75.5zM33 34h503v608h-503v-608zM199 731q0 -10 6.5 -16.5t16.5 -6.5h127q10 0 16.5 6.5t6.5 16.5q0 9 -6.5 15.5t-16.5 6.5h-127 q-10 0 -16.5 -6.5t-6.5 -15.5zM242 -72q0 -19 13.5 -32t32.5 -13t32 13t13 32t-13 32t-32 13t-32.5 -13t-13.5 -32z" />
<glyph unicode=")" horiz-adv-x="1106" d="M0 158v478q0 46 14 60t60 14h958q46 0 59.5 -14t13.5 -60v-478q0 -46 -13.5 -59.5t-59.5 -13.5h-406v-37h111v-58h-369v58h111v37h-405q-46 0 -60 13.5t-14 59.5zM37 150h1031v516h-1031v-516z" />
<glyph unicode="*" d="M0 582q0 25 16 45.5t41 26.5l197 47q-63 -72 -63 -168q0 -185 253 -283q28 -11 54 -24.5t54.5 -33.5t46 -46.5t17.5 -55.5q0 -43 -35 -67t-80 -24q-58 0 -121 22.5t-105 60.5l-79 -179q56 -31 144 -61q-10 -2 -31.5 -8.5t-38.5 -10t-32 -3.5q-25 0 -45.5 16t-26.5 41 l-164 687q-2 12 -2 18zM419 536q0 38 35 58.5t76 20.5q49 0 110 -17.5t88 -46.5l61 170q-90 48 -186 63q2 0 45 12t71.5 18t42.5 6q25 0 45.5 -16t26.5 -41l164 -687q2 -12 2 -18q0 -25 -16 -45.5t-41 -26.5l-145 -34q47 70 47 152q0 111 -70.5 182.5t-184.5 109.5 q-171 58 -171 140z" />
<glyph unicode="+" horiz-adv-x="1184" d="M0 -1q0 87 89 155t215 68h54q-42 40 -42 86q0 29 16 58q-10 -1 -29 -1q-104 0 -170 65t-66 160q0 91 82 159t187 68h310l-69 -50h-98q47 -18 73.5 -68t26.5 -111q0 -93 -88 -162q-37 -29 -48 -46t-11 -42q0 -19 27 -48t54 -49q61 -43 84.5 -88t23.5 -113 q0 -90 -82 -156.5t-222 -66.5q-133 0 -225 50t-92 132zM112 32q0 -69 58.5 -117.5t145.5 -48.5q119 0 172.5 44t53.5 117q0 19 -4 32q-3 11 -7 20.5t-12 19t-14 16t-19.5 16.5t-20.5 15t-25 17.5t-26 17.5q-39 12 -77 12q-90 1 -157.5 -47t-67.5 -114zM178 591 q11 -79 60.5 -136t109.5 -58q59 -2 94 52t25 133t-59.5 134t-109.5 57t-95 -51t-25 -131zM733 567v50h200v200h50v-200h201v-50h-201v-201h-50v201h-200z" />
<glyph unicode="," horiz-adv-x="1106" d="M0 673v21l2 2h249l2 -2v-20q0 -8 -10 -8l-26 -1q-33 -1 -33 -20q0 -13 7 -28q50 -122 222 -484l6 -1l111 221q-13 30 -22 49l-76 150l-20 40q-26 51 -34 60.5t-33 13.5q-14 2 -14 7v21l3 2h197l5 -1v-21q0 -8 -10 -8l-15 -2q-13 -2 -19 -5t-5.5 -12t4 -17.5t14.5 -30.5 l73 -150l81 162q16 32 5 43q-6 8 -37 11l-9 1q-4 0 -7 3q-3 1 -3 6v19l3 2q57 1 186 0l2 -2v-20q0 -8 -9 -8q-22 -1 -30.5 -4.5t-16.5 -15.5q-23 -34 -30 -48l-105 -196l-3 -7l128 -262l8 -3l202 481q12 28 -3 41q-13 12 -39 13l-19 1q-3 0 -6 3q-4 2 -4 6v20l3 2h229l2 -2 v-20q0 -7 -9 -9q-46 -2 -66 -19q-20 -16 -34 -49l-250 -567q-10 -23 -22.5 -30.5t-24 1t-22.5 30.5q-38 75 -122 263q-105 -216 -131 -264q-41 -71 -71 -1q-32 75 -130 284.5t-130 286.5q-16 42 -28 52q-11 10 -52 13q-14 2 -14 7z" />
<glyph unicode="-" horiz-adv-x="939" d="M-0.5 707q-0.5 11 6 20.5t13.5 16.5t23.5 15.5t27 13t33 14t34.5 14.5q54 22 97 16t54 -35q25 -67 102.5 -319.5t115.5 -361.5q268 88 326 105q16 6 37.5 4t32.5 -23q23 -47 32.5 -98.5t0.5 -74.5q-19 -15 -59.5 -32t-75.5 -29t-89.5 -29t-73.5 -23q-10 -3 -38 -13 t-53 -18.5t-58 -19t-61 -17.5t-54 -11.5t-44.5 -3.5t-25.5 9q-18 18 -32 52t-29 87t-19 66q-42 125 -113 338.5t-104 312.5q-6 13 -6.5 24z" />
<glyph unicode="." horiz-adv-x="778" d="M3 -129v775h92q0 29 0.5 39t4 31.5t11.5 30t24.5 16.5t40.5 8t40.5 -8t24 -16t11.5 -30.5t4 -31.5v-39h55v39t4 31.5t11.5 30.5t24 16t40.5 8q18 0 31 -4t21.5 -8.5t14.5 -17t8.5 -18.5t4 -24.5t1.5 -24.5v-28h54v28t1.5 24.5t4 24.5t8.5 18.5t14.5 17t21.5 8.5t31 4 q24 0 40.5 -8t24 -16t11.5 -30.5t4 -31.5v-39h92v-775h-776zM68 48v-112h139v112h-139zM68 70h139v119h-139v-119zM68 211h139v130h-139v-130zM68 362h139v112h-139v-112zM139 565q0 -33 37 -33t37 33v130q0 33 -37 33t-37 -33v-130zM228 48v-112h152v112h-152zM228 70h152 v119h-152v-119zM228 211h152v130h-152v-130zM228 362h152v112h-152v-112zM354 565q0 -33 37 -33q38 0 38 33v130q0 33 -38 33q-37 0 -37 -33v-130zM401 48v-112h152v112h-152zM401 70h152v119h-152v-119zM401 211h152v130h-152v-130zM401 362h152v112h-152v-112zM569 565 q0 -33 38 -33q37 0 37 33v130q0 33 -37 33q-38 0 -38 -33v-130zM574 48v-112h140v112h-140zM574 70h140v119h-140v-119zM574 211h140v130h-140v-130zM574 362h140v112h-140v-112z" />
<glyph unicode="/" horiz-adv-x="1309" d="M0 110v181h224v-179q0 -28 20 -48.5t49 -20.5t49.5 20t20.5 49v423q0 117 86.5 199.5t205.5 82.5t205.5 -83t86.5 -201v-92l-134 -40l-89 42v80q0 29 -20 49t-49 20t-49.5 -20t-20.5 -49v-417q0 -120 -86 -204.5t-206 -84.5q-121 0 -207 85.5t-86 207.5zM724 107v183 l89 -42l134 40v-184q0 -29 20 -49.5t49 -20.5t49 20.5t20 49.5v187h224v-181q0 -121 -85.5 -207t-206.5 -86t-207 85t-86 205z" />
<glyph unicode="0" horiz-adv-x="1258" d="M-5 196h119q5 -40 29.5 -64t64.5 -24q48 0 76.5 32.5t28.5 81.5q0 48 -28 79t-75 31q-38 0 -65 -24.5t-51 -24.5q-53 0 -80 2q9 52 28.5 160.5t28.5 164.5h330v-98h-243q-14 -71 -24 -134h3q17 21 50.5 32t65.5 11q113 0 160 -103q24 60 72 94t111 34q49 0 91 -19.5 t66 -41.5t63 -66q3 -3 4.5 -5t4 -4.5l4.5 -4.5q35 40 50 55.5t46 40.5t62 34.5t70 9.5q90 0 145 -60.5t55 -151.5q0 -93 -55 -156t-147 -63q-116 0 -226 131q-7 -7 -39 -38.5t-42.5 -39.5t-37 -25.5t-52 -23t-57.5 -5.5q-63 0 -111 33t-74 92q-62 -128 -203 -128 q-95 0 -156.5 47.5t-61.5 138.5zM510 226q0 -42 25.5 -68t67.5 -26q75 0 155 95q-34 35 -48 48.5t-47.5 33t-63.5 19.5q-39 0 -64 -31t-25 -71zM899 226q27 -29 45.5 -45.5t49 -32.5t61.5 -16q43 0 67.5 27.5t24.5 70.5q0 42 -25.5 70t-67.5 28q-25 0 -49 -11.5t-36.5 -21.5 t-37.5 -36t-32 -33z" />
<glyph unicode="1" horiz-adv-x="774" d="M0 458q0 63 26.5 125t76 115t130 86t178.5 33q159 0 261 -98t102 -231q0 -171 -86.5 -282.5t-223.5 -111.5q-45 0 -84.5 21t-55.5 51l-40 -158q-5 -19 -13 -38.5t-17.5 -37.5t-19 -34t-19 -30t-16.5 -23.5t-13 -16.5l-6 -8q-3 -4 -8 -3t-6 6q0 1 -1.5 14t-3 27.5t-3 37.5 t-1 44.5t3 47.5t7.5 48q11 47 74 313q-8 16 -13 38.5t-5 36.5l-1 15q0 64 32.5 106.5t78.5 42.5q37 0 57.5 -24.5t20.5 -61.5q0 -23 -8.5 -56.5t-22.5 -77t-20 -70.5q-10 -45 17.5 -78t73.5 -33q79 0 130.5 89.5t51.5 216.5q0 97 -63 158.5t-176 61.5q-126 0 -204.5 -81 t-78.5 -194q0 -67 38 -113q13 -15 8 -32q-2 -5 -6 -23t-6 -23q-2 -11 -10 -14.5t-18 0.5q-59 24 -88.5 82.5t-29.5 136.5z" />
<glyph unicode="2" d="M15 438q33 132 125.5 227.5t220.5 132.5t260 4t227.5 -125.5t132.5 -220.5t4 -260t-125.5 -227.5t-220.5 -132.5t-260 -4t-227.5 125.5t-132.5 220.5t-4 260zM243 167l72 -18q7 -1 20 -5t19 -5l-23 -91l55 -14l22 90q6 -2 21 -5.5t23 -5.5l-22 -90l55 -13l22 91 q48 -8 85.5 -7.5t66 20.5t42.5 61q32 90 -51 133q60 13 70 80q13 86 -110 126l23 91l-55 13l-22 -88q-8 2 -23 5.5t-21 5.5l22 88l-55 14l-22 -90q-15 2 -35 8l-76 19l-14 -59l39 -9q28 -7 26 -32l-26 -103q2 0 6 -2q-1 1 -3 1t-3 1l-36 -144q-5 -18 -25 -13l-40 10z M426 190l30 121q1 0 19.5 -4t28 -7t28 -9t28.5 -13t21 -16.5t14.5 -22t-0.5 -27.5q-3 -11 -9 -19t-15 -12t-18.5 -7t-23 -2.5t-23.5 1.5t-24 4t-21.5 4.5t-19.5 4.5t-15 4zM470 366l27 110q3 -1 12.5 -3t16.5 -3.5t18 -5t19 -6.5t18 -8.5t15 -11t11.5 -13.5t6 -16.5 t-1.5 -19.5q-3 -13 -10.5 -21.5t-19 -11.5t-22.5 -4.5t-26.5 1t-24 4t-23 5.5t-16.5 4z" />
<glyph unicode="3" horiz-adv-x="1129" d="M0 597h77l107 -363l72 244l-35 119h77l107 -363l107 363h77h213v-36l-109 -188q58 -20 86 -67q30 -50 30 -114q0 -82 -43 -137t-112 -55q-51 0 -90 33q-39 34 -56 89l60 25q13 -34 35 -54q20 -19 51 -19t52 34q22 34 22 84q0 52 -23 83q-27 34 -83 34h-30v36l103 178 h-124l-7 -12l-152 -511h-7l-110 370l-111 -370h-7zM818 180l18 -50q15 -33 33 -58q42 -58 94 -67q45 -9 88 18q19 12 35 31q20 20 28 36q4 7 11 20l-11 59q-8 -16 -16 -28t-12 -17l-4 -4q-34 -37 -61 -49q-33 -15 -68 -11q-27 2 -60 24q-36 31 -43 43q-13 18 -32 53z M845 375q0 84 33 146q16 30 37.5 48t42.5 20q35 4 70 -26q18 -15 37 -50l44 87l12 -76l-44 -85q-8 16 -19 30t-18 20l-8 6q-31 22 -64 15q-24 -5 -47.5 -30t-34.5 -59q-19 -55 -19 -106q-1 -40 5 -63q-12 22 -19 53t-7 51z" />
<glyph unicode="4" horiz-adv-x="1169" d="M0 377q0 105 76.5 179.5t184.5 74.5q85 0 152.5 -48t94.5 -124l66 64l158 -152l437 446v-405l-267 -206l34 -36l-363 -353l-316 307q-107 2 -182 76t-75 177zM37 377q0 -90 65 -153t157 -63q33 0 65 9l220 -195l585 460l1 302l-578 -596l-90 146q20 43 20 90 q0 89 -65.5 152.5t-157.5 63.5t-157 -63.5t-65 -152.5zM85 375q0 70 49.5 119.5t119.5 49.5t119.5 -49t49.5 -120q0 -70 -49.5 -119.5t-119.5 -49.5t-119.5 49.5t-49.5 119.5z" />
<glyph unicode="5" horiz-adv-x="710" d="M16 619h699l-66 -710l-284 -81l-284 81zM81 679v133h45v-44h40v44h44v-133h-44v44h-40v-44h-45zM146 474l24 -266l1 2h300l-10 -113l-96 -27l-97 28l-6 68h-88l12 -136l179 -51l179 51l25 267h-319l-8 89h335l8 88h-439zM230 767v45h122v-45h-39v-88h-44v88h-39zM371 679 v133h47l27 -46l28 46h47v-133h-43v68l-32 -50v1l-30 47v-66h-44zM543 679v133h44v-88h62v-45h-106z" />
<glyph unicode="6" horiz-adv-x="943" d="M0 -32.5q-3 35.5 7 59.5q39 140 92 239q114 216 313 352v14q-59 -25 -118.5 -65.5t-102 -81t-76 -77.5t-50.5 -60l-17 -23q-2 59 16 115t45 94t54.5 67t46.5 43l19 13q4 2 10.5 5.5t27.5 13.5t43.5 18.5t55 17t64 12t70 2t73.5 -11.5q64 47 128.5 73t97.5 29l33 3 q50 5 77.5 -16.5t31 -55t-0.5 -68t-12 -59.5l-9 -24l-5 5q21 57 20.5 93.5t-17.5 56.5t-36.5 29t-36.5 10l-16 2q-4 0 -11.5 -0.5t-32 -5t-49 -12.5t-60.5 -25t-69 -41q69 -11 123 -42t86 -70.5t54.5 -85t31 -88.5t13 -78t3.5 -56l-1 -22h-557q-3 -42 10.5 -73t34 -45.5 t41 -22.5t35.5 -9l15 -1q4 0 11.5 0.5t26.5 5.5t34.5 14t31 28.5t21.5 46.5h292q-16 -59 -47 -107t-68 -77.5t-78 -51t-78.5 -31.5t-68 -16t-48.5 -7h-19q-78 0 -107 6q-60 -47 -126.5 -73.5t-103.5 -29.5l-36 -3q-46 0 -77.5 23.5t-41.5 56t-13 68zM75.5 -27 q-0.5 -24 2.5 -42.5t8 -28.5l4 -9q4 -3 11 -8t33.5 -13.5t57 -8t82 16.5t107.5 50q-8 2 -21.5 5.5t-50.5 18t-69 31.5t-66.5 47.5t-53.5 64.5q-22 -34 -33 -67t-11.5 -57zM358 397h265q1 36 -11.5 63t-32 39t-38.5 19t-33 8l-14 1q-6 0 -15 -1t-33 -8t-42 -19t-32.5 -39 t-13.5 -63z" />
<glyph unicode="7" horiz-adv-x="900" d="M42 581q2 17 15 32l120 120q14 12 21 -4l97 -182q8 -16 -5 -31l-44 -44q-12 -12 -14 -31q0 -30 31 -77t61 -80l31 -32q14 -14 36 -34.5t72.5 -54t79.5 -33.5q19 0 32 13l52 52q14 14 30 4l175 -103q7 -4 8 -10.5t-4 -11.5l-120 -120q-15 -13 -32 -15q-49 -7 -110.5 13.5 t-114 54.5t-97.5 69t-72 60l-26 25q-10 10 -26.5 27.5t-57.5 69t-71 100.5t-52 111.5t-15 111.5z" />
<glyph unicode="8" d="M0 318q0 136 67 251t182 182t251 67t251 -67t182 -182t67 -251t-67 -251t-182 -182t-251 -67t-251 67t-182 182t-67 251zM129 318q0 -65 36 -77q5 -2 17 -4q42 -1 85 40q41 36 58 90q25 77 10 200q-2 12 -2 17q-3 6 0 9q1 3 13 -1q38 -10 78 -29q46 -21 102 -70 q45 -39 87 -89q33 -39 80 -104q41 -57 88 -77q29 -10 47.5 -7t29 20t15 37t4.5 45q0 48 -12 96q-3 12 -8 28q-14 43 -41 84q-52 79 -135.5 124t-177.5 45q-66 0 -125 -22q-80 -28 -140.5 -89t-88.5 -142q-1 -5 -4 -14.5t-5 -13.5q-12 -50 -11 -96z" />
<glyph unicode="9" horiz-adv-x="1220" d="M0 669q-1 5 2.5 9.5t8.5 5.5q11 2 31 6.5t28 6.5q0 17 1 49.5t1 48.5q2 12 13 12q14 0 14 -14q-2 -60 -2 -91q11 2 35 7t35 8q18 4 55 10t56 10q402 69 794 72q6 0 9.5 -4.5t2.5 -10.5q0 -11 -2 -33t-2 -33q42 -3 128 -11q5 0 9 -4.5t3 -9.5q-23 -137 -68 -412t-68 -413 q50 -8 76 -12q8 -1 10.5 -8t-0.5 -13t-10 -6h-3q-13 2 -39 6.5t-39 6.5q-1 -12 -5 -31q-2 -9 -10 -11q-1 -1 -4 -1h-4q-297 75 -600 117q-100 2 -149 2q-55 0 -165 -2v-1q1 -1 1 -2q1 -6 -4 -10.5t-11 -4.5q-11 0 -12 11q0 5 -1.5 15.5t-2.5 16.5h-13q-8 0 -10.5 7t1 13.5 t11.5 6.5h1h7l-6 54q-6 40 -25 194.5t-35.5 251.5t-42.5 191zM30 661q21 -78 43 -201q-3 70 -3 209q-16 -2 -40 -8zM97 570q1 -193 21 -424q3 -40 11 -109q1 -9 2.5 -19t3.5 -22t3 -19q67 -3 192 -13t182 -13q354 -20 483 -35q11 160 32.5 455t29.5 411q-468 -4 -960 -107 q-1 -53 0 -105zM189 407q0 -68 42.5 -111t108.5 -43q69 0 109 43h2q-13 -70 -65 -111q-41 -33 -101 -38q-40 -4 -52 -2v-75q35 0 57 2q107 8 171 68q87 82 87 233q0 94 -47 153.5t-132 59.5q-78 0 -129 -53t-51 -126zM283 413q0 45 22.5 73.5t58.5 28.5h1q43 0 65 -35.5 t21 -90.5q0 -16 -5 -26q-26 -42 -81 -42q-38 0 -60 26t-22 66zM372 -64l96 -10l373 -40q140 -30 209 -48l3 18q-55 9 -165 25q-249 35 -516 55zM564 407q0 -68 43 -111t108 -43q69 0 110 43h1q-13 -70 -64 -111q-42 -33 -102 -38q-40 -4 -52 -2v-75q35 0 57 2q107 8 171 68 q87 80 87 233q0 94 -47 153.5t-131 59.5q-78 0 -129.5 -53t-51.5 -126zM658 413q0 45 23 73.5t58 28.5h1q43 0 65 -35.5t21 -90.5q0 -16 -5 -26q-26 -42 -81 -42q-38 0 -60 26t-22 66zM1015 -111q28 -4 43 -6q20 120 64.5 392t68.5 417q-13 1 -35.5 3t-41.5 3.5t-36 2.5 q-6 -85 -27 -366.5t-31 -435.5q0 -5 -4 -9q-1 0 -1 -1z" />
<glyph unicode=":" horiz-adv-x="834" d="M0 -180l417 1000l417 -1000h-369v135l170 85l-13 55l-157 -79v67l98 52l-14 57l-84 -45v87h-92v-157l-86 59l-16 -64l102 -70v-182h-373z" />
<glyph unicode=";" horiz-adv-x="1123" d="M-1 52v372q0 13 13 13h176v129q0 14 13 14h98v-514q0 -14 -12 -14h-288zM108 135h67q13 0 13 14v206h-67q-13 0 -13 -14v-206zM333 52v372q0 13 13 13h98v-371q0 -14 -12 -14h-99zM333 497v69q0 14 12 14h99v-69q0 -14 -12 -14h-99zM482 52v372q0 13 13 13h288v-504 q0 -13 -13 -13h-288l1 69q0 14 12 14h176v49h-189zM592 135h67q12 0 12 14v206h-67q-12 0 -12 -14v-206zM821 -11q0 14 13 14h176v49h-189v372q0 13 13 13h287v-504q0 -13 -12 -13h-288v69zM930 135h67q13 0 13 14v206h-67q-13 0 -13 -14v-206z" />
<glyph unicode="&#x3c;" d="M0 329q0 73 51.5 125t124.5 52q63 0 114 -43l358 179q0 2 -0.5 5.5t-0.5 5.5q0 73 52 124.5t125 51.5t124.5 -51.5t51.5 -124.5t-51.5 -125t-124.5 -52q-64 0 -114 42l-358 -179q0 -1 0.5 -4.5t0.5 -5.5q0 -1 -0.5 -5t-0.5 -5l358 -179q50 42 114 42q73 0 124.5 -51.5 t51.5 -124.5t-51.5 -125t-124.5 -52q-74 0 -125.5 51.5t-51.5 125.5q0 1 0.5 4.5t0.5 5.5l-358 179q-50 -42 -114 -42q-73 0 -124.5 51.5t-51.5 124.5z" />
<glyph unicode="=" d="M0 319q0 136 67 251t182 182t251 67t251 -67t182 -182t67 -251q0 -101 -38 -192t-107 -160q-60 73 -145.5 114t-182.5 41q-107 0 -199 -49.5t-151 -134.5q-83 71 -130 170t-47 211zM164 463q0 -17 12 -29.5t30 -12.5q6 0 9 1q144 58 298 58t298 -58q1 0 4 -0.5t5 -0.5 q17 0 29.5 12.5t12.5 29.5q0 25 -23 37q-159 63 -326 63q-170 0 -329 -64q-20 -13 -20 -36zM210 314l6 -16q8 -13 23 -13q3 0 9 2q127 55 265 55q139 0 267 -56q4 -2 7 -2q15 0 23 13l5 17q0 13 -10 21q-138 62 -292 62q-153 0 -293 -62q-10 -10 -10 -21zM258 170 q10 -25 31 -16q108 51 224 51q112 0 219 -48q24 -13 35 12q5 13 0 23t-14 15q-106 53 -240 53q-128 0 -244 -55q-19 -10 -11 -35zM319 -147q37 48 91.5 76t116.5 28q114 0 193 -86q-104 -52 -220 -52q-94 0 -181 34z" />
<glyph unicode="&#x3e;" horiz-adv-x="1205" d="M0 323q0 62 49.5 106t112.5 44q62 0 105 -36h5q134 82 335 82l5 4l70 267l242 -36q0 -1 2 -1q1 0 0 1q2 1 11.5 15.5t14.5 18.5q34 32 82 32q49 0 82.5 -32.5t33.5 -81.5t-33.5 -84t-82.5 -35q-57 0 -87 38.5t-30 96.5q-2 -1 -97.5 13t-109.5 17h-3q-2 -2 -16.5 -53.5 t-30 -109t-17.5 -63.5v-3l5 -4q72 0 147.5 -20.5t130.5 -57.5l3 -2q1 1 2 1t2 1q25 18 35.5 25t29.5 13t43 6q68 0 116 -48t48 -117q0 -47 -26.5 -86t-69.5 -60q0 -195 -260 -303q-41 -18 -56 -23q-32 -10 -91 -19t-93 -9q-120 0 -231 35q-2 2 -72 38q-95 51 -152.5 116 t-57.5 156h-5q-33 17 -59 50l-9 12q-15 27 -19 45.5t-4 50.5zM34 311q0 -66 57 -112q5 59 48 116t101 101q-37 26 -82 26q-49 0 -86.5 -40.5t-37.5 -90.5zM136 165q0 -54 31 -104t79.5 -85.5t102.5 -59.5t105 -34q75 -14 146 -14q123 0 233 39.5t185 122.5h-3q30 38 43 68.5 t13 72.5q0 54 -26.5 103t-69.5 84t-92 60.5t-100 38.5q-85 23 -181 23q-74 0 -151.5 -18t-150 -54t-118.5 -99.5t-46 -143.5zM322 238q0 37 22.5 59.5t59.5 22.5t62 -22.5t25 -59.5q0 -36 -25.5 -60t-61.5 -24t-59 24t-23 60zM358 74h44q25 -45 79.5 -68.5t111.5 -23.5 q58 0 110 23.5t84 68.5h41q-25 -62 -93 -96t-142 -34q-72 0 -141.5 34.5t-93.5 95.5zM694 238q0 38 23 60t61 22q34 0 58 -24t24 -58t-24 -59t-58 -25q-37 0 -60.5 23.5t-23.5 60.5zM949 706q0 -35 25 -60t60 -25q36 0 59 24.5t23 60.5q0 34 -24 58t-58 24t-59.5 -24.5 t-25.5 -57.5zM963 425q55 -36 95 -92.5t56 -119.5q59 43 59 96q0 58 -35.5 100t-92.5 42q-45 0 -82 -26z" />
<glyph unicode="?" horiz-adv-x="767" d="M2 27q0 22 12 64q23 87 86.5 158t147.5 103q-79 63 -79 161q0 86 62.5 146t148.5 60t148.5 -60t62.5 -146q0 -97 -77 -160q106 -38 177 -127t71 -198q0 -92 -73 -106q-3 -10 -13 -26q-6 -16 -23.5 -28.5t-48.5 -20.5t-49.5 -12t-56.5 -9t-39 -5q-2 0 -7 -1t-7 -1h-120 q-51 0 -129 16.5t-89 44.5q-17 17 -25 42q-25 5 -42 21q-38 15 -38 84z" />
<glyph unicode="@" horiz-adv-x="772" d="M4 308v103q0 87 86 200t171 160q78 44 187 44q44 0 88.5 -10t85.5 -31t66.5 -58t25.5 -85q0 -13 -2 -24.5t-7 -24t-9 -21t-14 -21t-14 -18.5t-17.5 -19.5t-16.5 -17t-18.5 -17.5t-17.5 -16h53h115q2 -72 2 -108q0 -253 -42 -326q-35 -61 -94.5 -108t-127.5 -70 q-39 -15 -56 -15h-84q-3 0 -48 17q-120 53 -120 174q0 4 0.5 11t0.5 10q-134 69 -180 215q-13 42 -13 56zM150 438q0 -40 9.5 -81t28.5 -79t52.5 -62t76.5 -24q12 0 39.5 15t49.5 15q14 0 51 -10.5t37 -19.5q0 -21 -26 -21q-130 0 -130 -76q0 -58 42 -87.5t103 -29.5 q47 0 92 16.5t73 49.5q42 50 42 164q0 19 -1 55.5t-1 54.5q0 48 5 80h-193q-1 -8 -1 -23q0 -11 1 -34t1 -35q0 -35 -8 -56q-5 -1 -17 -1q-48 0 -80 32.5t-44 74.5t-12 89q0 45 11.5 91t43 84t77.5 38q10 0 21 -3q-4 -22 -4 -34q0 -35 19 -58t53 -23t57 23t23 58q0 41 -31 70 t-70 40t-79 11q-135 0 -223 -85t-88 -219z" />
<glyph unicode="A" horiz-adv-x="860" d="M1 361q-1 -18 -1 -36q0 -68 20 -144q26 -97 83 -184q89 -136 172 -137q30 0 78 21t95 21h4q46 0 91 -20q47 -22 76 -22q49 1 91 41t85 104q31 48 65 121q-50 19 -85 57t-48 85q-10 35 -9 70v24q4 48 33.5 91.5t78.5 70.5q-38 48 -89 75t-103 27q-48 0 -105.5 -21.5 t-85.5 -21.5q-30 0 -90.5 21.5t-101.5 21.5q-58 0 -114.5 -33.5t-95.5 -92.5q-37 -56 -44 -139zM416 619q-3 15 -3 30q0 65 53 129q27 33 69.5 56t82.5 26q2 -15 2 -30q0 -69 -50 -132q-28 -36 -70 -58q-41 -22 -80 -21h-4z" />
<glyph unicode="B" horiz-adv-x="996" d="M0 135v369q0 130 93 223t223 93h221q65 -8 138.5 -57t104.5 -115q1 -2 5 -9.5t5 -10t3.5 -9.5t4 -12.5t3.5 -15.5t4 -22t4 -29q9 -70 26 -85q14 -13 71 -14.5t65 -7.5l14 -11l8 -17l3 -14l-2 -256q-1 -130 -93 -222.5t-222 -92.5h-363q-130 0 -223 92.5t-93 222.5z M259 140q0 -25 18 -42.5t43 -17.5h356q25 0 42.5 17.5t17.5 42.5t-17.5 42.5t-42.5 17.5h-356q-25 0 -43 -17.5t-18 -42.5zM259 502q0 -25 18 -43t43 -18h175q25 0 42.5 18t17.5 43t-17.5 42.5t-42.5 17.5h-175q-25 0 -43 -17.5t-18 -42.5z" />
<glyph unicode="C" d="M0 320q0 98 38 191q37 90 110 163q144 146 351 146q209 0 357 -146q71 -71 107 -162q37 -89 37 -192q0 -104 -36 -192q-36 -89 -107 -159q-74 -72 -166 -111q-94 -38 -192 -38q-97 0 -190 38q-89 37 -162 110t-110 162t-37 190zM90 320q0 -79 32 -155q31 -75 91 -133 q60 -60 133 -89q72 -31 155 -31q81 0 156 31q74 31 136 90q117 114 117 287q0 85 -31 157q-30 76 -88 132q-120 121 -290 121q-171 0 -288 -120q-59 -59 -91 -134q-32 -76 -32 -156zM215 320q0 71 42 113q41 42 105 42q92 0 133 -72l-67 -35q-11 24 -27 31q-15 9 -29 9 q-67 0 -67 -88q0 -39 17 -64q18 -24 50 -24q44 0 62 42l62 -31q-21 -36 -55 -57q-35 -21 -77 -21q-67 0 -108 41t-41 114zM504 320q0 71 42 113t105 42q93 0 132 -72l-66 -35q-11 23 -26 31q-17 9 -30 9q-67 0 -67 -88q0 -41 17 -64q17 -24 50 -24q43 0 61 42l63 -31 q-22 -37 -56 -57q-35 -21 -75 -21q-69 0 -109 41q-41 41 -41 114z" />
<glyph unicode="D" d="M0 320q0 136 67 251t182 182t251 67t251 -67t182 -182t67 -251t-67 -251t-182 -182t-251 -67t-251 67t-182 182t-67 251zM83 320q0 -156 105 -275q48 94 152 179t203 107q-15 35 -29 63q-172 -55 -372 -55q-39 0 -58 1q0 -4 -0.5 -10t-0.5 -10zM96 423q22 -2 65 -2 q167 0 317 45q-76 135 -167 225q-79 -40 -135.5 -111t-79.5 -157zM245 -9q113 -88 255 -88q74 0 147 28q-20 171 -78 331q-92 -20 -185.5 -101t-138.5 -170zM398 723q88 -91 163 -227q136 57 205 145q-116 96 -266 96q-51 0 -102 -14zM597 425q15 -32 34 -81q74 7 161 7 q62 0 123 -3q-8 136 -98 242q-65 -97 -220 -165zM656 274q51 -148 69 -304q79 51 129 131t60 173q-73 5 -133 5q-55 0 -125 -5z" />
<glyph unicode="E" horiz-adv-x="837" d="M0 511q0 40 15 58q9 14 26 21q18 9 47 9h94q15 0 26 11t11 26q0 21 -1 44v59q0 25 12 44q15 21 50 31q11 6 53 6h19q59 -2 98 -17q38 -16 45 -62q26 1 48 1q53 0 89 -5q97 -12 129 -24q42 -13 53 -67q10 -55 18 -210q5 -89 5 -147q0 -44 -3 -71q-16 -172 -43 -254 q-14 -42 -28 -68.5t-27.5 -42.5t-36.5 -23t-42.5 -8.5t-58.5 -1.5q-108 0 -145.5 25.5t-37.5 106.5q0 45 9.5 71.5t33 37.5t46.5 13q15 1 40 1h28q4 0 5.5 -1.5t0.5 -5t-2.5 -7.5t-3 -11t-1.5 -13q0 -9 2 -18.5t1 -12t-7 -2.5h-9.5h-10.5t-10 -0.5t-10 -1.5t-8.5 -2.5t-8 -4 t-5.5 -6t-4 -9t-1 -11.5q0 -14 4 -23t7.5 -14t18 -7t22 -2h32.5q57 0 73 13.5t16 63.5q0 76 -18.5 102.5t-56.5 31.5q-88 9 -119 20q-53 20 -53 119q0 2 -2.5 2t-2.5 -2q0 -67 -18 -120l-8 -24q-11 -25 -37 -26h-6q-24 0 -54 8q-127 16 -198 47q-24 11 -37 40 q-17 35 -35.5 128.5t-23.5 133.5q-4 33 -4 51zM6 630v2l183 180q0 1 1 1l-3 -6q-11 -20 -11 -48q0 -22 1 -103q0 -10 -10 -10h-93q-34 0 -59 -11q-5 -3 -9 -5zM574 340q21 3 46 3q45 -1 81 -18q0 85 -61 87h-3q-30 0 -44 -20q-15 -21 -19 -52z" />
<glyph unicode="F" horiz-adv-x="1053" d="M0 260q0 104 73 177t177 73t177 -73t73 -177t-73 -177t-177 -73t-177 73t-73 177zM552 260q0 104 73 177t177 73t177 -73t73 -177t-73 -177t-177 -73t-177 73t-73 177z" />
<glyph unicode="G" horiz-adv-x="646" d="M0 -1q0 87 89 155t215 68h54q-42 40 -42 86q0 29 16 58q-10 -1 -29 -1q-104 0 -170 65t-66 160q0 91 82 159t187 68h310l-69 -50h-98q47 -18 73.5 -68t26.5 -111q0 -93 -88 -162q-37 -29 -48 -46t-11 -42q0 -19 27 -48t54 -49q61 -43 84.5 -88t23.5 -113 q0 -90 -82 -156.5t-222 -66.5q-133 0 -225 50t-92 132zM112 32q0 -69 58.5 -117.5t145.5 -48.5q119 0 172.5 44t53.5 117q0 19 -4 32q-3 11 -7 20.5t-12 19t-14 16t-19.5 16.5t-20.5 15t-25 17.5t-26 17.5q-39 12 -77 12h-4q-87 0 -153 -47q-68 -48 -68 -114zM178 591 q11 -79 60.5 -136t109.5 -58h4q56 0 90 52q27 42 27 99q0 16 -2 34q-10 79 -59.5 134t-109.5 57h-4q-57 0 -91 -51q-27 -41 -27 -98q0 -16 2 -33z" />
<glyph unicode="H" horiz-adv-x="878" d="M0 194q0 -147 101 -257t260 -110q158 0 259 110q101 108 101 257q0 78 -27 146q-40 -25 -85 -34q22 -51 22 -114q0 -76 -36 -142q-37 -66 -99 -101q-62 -36 -135 -36q-75 0 -136 36q-63 37 -98 101q-37 65 -37 142q0 117 80 202q80 83 191 83q51 0 98 -19q4 39 27 86 q-57 21 -125 21q-160 0 -266 -118q-95 -107 -95 -253zM280 -59l56 -4q74 47 124.5 109t72.5 124t31 126q6 41 6 80q0 21 -2 40q-5 55 -12.5 98.5t-15.5 68.5l-9 25q-22 68 -43.5 119t-31.5 67l-11 17q39 -20 63 -48q23 -29 28 -53q4 -20 4 -39v-7q-1 -22 -6 -35l-5 -13 q4 -58 5 -112q0 -52 -5 -102q-9 -100 -30.5 -167t-49.5 -121.5t-57.5 -85.5t-54.5 -51.5t-41 -28.5zM555 578q4 40 23 64l18 25q12 14 39 26.5t48 18.5l21 6q36 8 66.5 35t43.5 51l13 23q41 -57 49 -129q4 -32 3 -57q0 -34 -6 -59l-11 -45q-12 -33 -33.5 -60t-36.5 -37 l-15 -11q-34 -20 -67 -20l-109 53q58 32 101 65t63.5 57.5t33 44.5t14.5 31l2 10q-18 -40 -48.5 -73t-62 -52t-60.5 -32.5t-47 -18.5l-18 -5q-25 44 -25 79q0 5 1 10z" />
<glyph unicode="I" horiz-adv-x="487" d="M-2 -148q102 6 130 27q30 21 30 107v666q0 82 -30 106q-28 23 -130 28v28h489v-28q-102 -4 -131 -28q-30 -24 -30 -106v-666q0 -86 30 -107t131 -27v-28h-489v28z" />
<glyph unicode="J" horiz-adv-x="1234" d="M0 145q0 161 184 347q117 116 236 162q56 23 97 23q45 0 72 -27q26 -26 26 -72q0 -31 -12 -72q-4 -14 3 -17.5t16 -0.5l10 4q96 40 170 40t106 -42q15 -22 15 -52q0 -31 -16 -71q-7 -10 -2.5 -17t8 -9t14.5 -5q62 -19 106 -62t44 -107q0 -59 -41 -120.5t-111.5 -112.5 t-178 -84t-228.5 -33q-131 0 -247.5 38.5t-193.5 115t-77 174.5zM125 97q10 -101 125 -161q92 -49 209 -49q29 0 60 3q153 15 255 97q92 75 92 165q0 9 -1 18q-10 100 -125 160q-93 49 -210 49q-29 0 -59 -3q-101 -10 -183 -51t-126 -101q-38 -53 -38 -109q0 -9 1 -18z M285 35q-13 29 -13 59q0 35 18 70q31 64 104 96q45 20 91 20q27 0 54 -7q76 -20 109 -82q17 -32 17 -66q0 -32 -15 -65q-31 -71 -109 -104q-44 -19 -88 -19q-34 0 -67 11q-73 23 -101 87zM341 54q6 -25 30 -35q13 -6 27 -6q12 0 24 4q28 9 43 33q10 16 10 32q0 7 -3 15 q-6 24 -30 34q-13 5 -26 5q-12 0 -25 -4q-27 -9 -41 -32q-11 -16 -11 -33q0 -7 2 -13zM482 133q3 -9 13 -13q5 -2 9.5 -2t9.5 2q11 4 16 13t2 18t-12 13q-9 3 -19.5 -0.5t-15.5 -12.5q-3 -6 -3 -12v-6zM803 754q-1 5 -1 10q0 13 8 25q10 16 29 21q34 7 68 7q51 0 100 -15 q83 -27 143 -93t78 -153q7 -35 7 -68q0 -51 -16 -98v-1q-6 -18 -23 -27q-11 -5 -22 -5q-7 0 -15 2q-19 6 -27 23q-5 11 -5 21q0 8 2 15v1q11 34 11 70q0 23 -4 48q-13 62 -56 109t-102 66q-35 10 -70 10q-24 0 -49 -5q-5 -1 -10 -1q-14 0 -26 8q-16 11 -20 30zM843 597 q-1 5 -1 10q0 10 6 21q9 14 26 18q19 4 37 4q67 0 115 -53q29 -33 38 -75q3 -17 3 -33q0 -24 -8 -48q-5 -16 -20 -23q-9 -5 -18 -5q-7 0 -13 2q-16 5 -24 20q-4 9 -4 18q0 7 2 13q4 14 4 26q0 28 -21 50q-22 26 -54 26q-10 0 -20 -2q-5 -1 -9 -1q-11 0 -21 7q-14 9 -18 25z " />
<glyph unicode="K" horiz-adv-x="1086" d="M0 -182v1000h257v-371h229q85 123 257 371h286l-328 -477q0 -12 96.5 -143t192.5 -256l96 -124h-343q-47 66 -143 199.5t-143 200.5h-200v-400h-257z" />
<glyph unicode="L" horiz-adv-x="1040" d="M-5 699q0 50 35 82.5t91 32.5q55 0 89 -32q35 -33 35 -86q0 -48 -34 -80q-35 -33 -92 -33h-1q-55 0 -89 33t-34 83zM8 -176v668h222v-668h-222zM353 -176h222v373q0 35 8 54q14 34 42.5 57.5t71.5 23.5q112 0 112 -151v-357h222v383q0 148 -70 224.5t-185 76.5 q-129 0 -201 -111v-2h-1l1 2v95h-222q2 -32 2 -199t-2 -469z" />
<glyph unicode="M" horiz-adv-x="1348" d="M0 276q0 35 2 105q24 8 48 8h18q17 -23 40 -70t31 -61q2 7 8 36.5t10 42.5t11 36.5t15.5 40.5t19.5 31q28 -5 46 -5q6 0 11 1q24 -54 45.5 -163t38.5 -155q-1 0 -4 1l-3 1q-9 0 -26 -5.5t-22 -6.5q-40 101 -62 203q-15 -26 -15 -89t-11 -88l-5 2q-8 0 -22 -2t-21 -2h-18 q-27 48 -57 89q-3 -6 -3 -15t2.5 -26t2.5 -25l-1 -12q-30 -15 -52 -15q-7 0 -10 1q-17 56 -17 142zM355 200q0 27 8 57.5t28 57t47 26.5q10 0 28 -5t23 -6q9 -40 9 -81q0 -28 -6 -55q-12 4 -38 4.5t-37 3.5q-5 -20 -5 -37q0 -21 10 -37t30 -16q9 0 26 5t26 5q17 0 23 -14 q-42 -16 -82 -16q-46 0 -68 30t-22 78zM413 228l8 1q3 0 8 -2t7 -2l7 3q2 14 2 22q0 18 -5 40q-22 -25 -27 -62zM523 174q0 123 78 182q32 -3 60 -23q-1 -17 -8 -67q-5 -39 -5 -65v-14q-20 -2 -29 -2q-8 0 -43 5q-5 -12 -5 -23q0 -22 17 -37.5t39 -15.5q26 0 41 23 q18 -6 21 -17q-22 -21 -63 -21q-37 0 -70 20t-33 55zM579 217q4 -6 14 -6h9q9 19 9 49q0 13 -6 39q-3 -8 -10 -25t-11.5 -30.5t-4.5 -26.5zM678 236q-2 26 23 26q6 0 18 -1t17 -1q3 15 3 31q0 29 -7.5 86.5t-7.5 86.5q0 43 10 72q5 -3 26.5 -5.5t40.5 -24.5q-6 -26 -6 -67 q0 -20 4 -81q2 -35 2 -61q0 -20 -1 -34h6q7 0 9 6t2 12.5t4 6.5q8 0 18.5 -8.5t22.5 -21.5t15 -16q-9 -7 -40.5 -9t-38.5 -4q-1 -12 -1 -36q0 -16 0.5 -33t1.5 -38t1 -33q-8 -1 -23 -2t-22 -2v10v10q0 21 -3 57q-4 44 -4 61q-6 2 -32 3.5t-38 9.5zM893 244q0 20 2 58 q11 -1 20 -5t21 -10.5t18 -9.5l-1 -27q0 -59 9 -116q19 7 31 23t16.5 41.5t5.5 42t2 44.5v11q3 -1 9 -1q20 -2 49 -25q0 -3 0.5 -9.5t0.5 -9.5q0 -15 -4 -30t-7.5 -22t-14.5 -25t-14 -23q-15 -12 -34 -42q-21 -7 -38 -7q-71 0 -71 142zM1093 136q7 6 24 10q0 3 1 9 q4 35 7 56.5t12.5 59t22 59.5t35.5 39.5t53 17.5q34 0 76 -24q17 -37 17 -75q0 -66 -46.5 -119t-112.5 -68q-2 -32 -2 -48q0 -73 18 -117q-8 2 -37 2q-15 0 -22 2q-9 21 -16.5 96t-29.5 100zM1183 161q39 10 65.5 48t26.5 79q0 30 -15 56q-23 -21 -39.5 -55.5t-23 -60 t-14.5 -67.5z" />
<glyph unicode="N" horiz-adv-x="1213" d="M-9 598q10 8 25 12q14 4 25 4h9q10 0 24 -1q22 -1 32 -1q6 0 38 2q16 1 29 0.5t23 -0.5q20 -2 32 -8q6 -3 13 -13t11.5 -19t11.5 -25.5t10 -21.5q38 -82 94 -163q2 -3 7 -11t8.5 -12.5t9 -11.5t10.5 -11t10.5 -8.5t11.5 -5.5t12 0q28 5 31 117q1 19 1 35q0 74 -15 102 q-6 11 -15.5 17.5t-24.5 12t-23 10.5q14 28 49.5 37t96.5 9h25h28t26 -0.5t27 -3l22 -5.5t19.5 -9t12.5 -14q9 -18 11 -42q0 -7 1 -14q0 -20 -3 -52q-4 -42 -4 -52q-3 -23 -3 -46q0 -18 2 -38q4 -44 30 -61q9 1 16.5 4t15.5 11t11 11.5t12.5 16.5t10.5 14q47 62 94 163 l9 22.5t11.5 26.5t12 19.5t15.5 13.5q16 7 38 7h9q20 0 46 -2q32 -2 47 -2q9 0 27.5 1t32.5 1.5t29.5 -0.5t25.5 -6t14 -13q3 -6 3 -13q0 -29 -35 -87q-17 -29 -34.5 -52.5t-45.5 -58t-37 -46.5q-2 -2 -14 -18t-17.5 -24t-11.5 -22.5t-5 -26.5q0 -8 3 -15t9.5 -15t10 -12 t13.5 -13t12 -11q71 -65 112 -117q40 -52 40 -75q0 -33 -51 -41q-26 -4 -53 -4q-21 0 -43 3q-20 2 -37 2q-26 0 -45 -5h-6q-66 11 -139 94q-4 4 -17 20.5t-22 25.5t-23 17t-27 6q-23 -4 -30.5 -29t-9 -59.5t-9.5 -48.5q-13 -24 -79 -24q-28 0 -66 4q-78 8 -141.5 40 t-100.5 67.5t-81 92.5q-104 133 -197 322q-3 6 -11 22.5t-12 25.5t-9.5 23.5t-8 28t-2.5 26.5z" />
<glyph unicode="O" horiz-adv-x="852" d="M2 287q-1 19 -2 40q0 33 4 73q6 66 24 123q2 7 6.5 18.5t21.5 44t37.5 62t54.5 64.5t72 59q40 25 94 39q41 11 84 10q15 0 30 -1q107 0 191 -44t133.5 -116t74.5 -155t25 -169q0 -279 -160 -425q-55 -50 -121 -68t-157 -21h-11q-39 0 -83 12q-50 14 -105 44t-103 88 t-75 136q-3 9 -8 25t-14 64.5t-13 96.5zM224 189q4 -55 8 -79.5t7 -31.5q8 -66 30 -112.5t47.5 -66.5t49.5 -30.5t40 -10.5h16q54 1 91.5 22.5t59.5 66t33.5 100.5t17.5 139q2 81 2 143q0 47 -1 84q-3 86 -9 123l-5 37q-8 37 -15.5 62t-22.5 55t-33 48t-47.5 30.5 t-67.5 12.5q-10 1 -19 1q-30 0 -56 -14q-34 -20 -53.5 -51.5t-33 -63.5t-17.5 -55l-5 -24q-6 -46 -10 -110t-5 -105v-41q-3 -44 -3 -80q0 -26 1 -49z" />
<glyph unicode="P" horiz-adv-x="1049" d="M0 207q10 139 168 173q12 89 42.5 192t71.5 146q48 49 120 75.5t146 26.5q86 0 164 -39t117 -110q19 -36 41.5 -130.5t30.5 -154.5q15 -6 34 -6q30 0 30 29q0 11 -6 33.5t-5 35.5v4h1q27 0 61 -51q34 -52 34 -81q0 -20 -9.5 -35.5t-19 -24.5t-33 -17.5t-32.5 -10.5 l-36 -8q-5 -1 -8 -2v-26q0 -173 -77 -253l25 -25q4 -2 25 -11.5t35.5 -18.5t18.5 -18q-65 -51 -132 -51q-34 0 -75 17q-88 -37 -180 -37q-118 0 -234 61q-36 -8 -55 -19q-7 -4 -26.5 -18t-36.5 -23.5t-28 -9.5q-3 18 -3 37q0 79 53 126q-60 99 -62 257l-7 1h-3 q-30 1 -76 -17q-48 -18 -64 -19q-4 0 -10 2zM232 114q0 -13 7 -27q27 -96 89 -138q43 -29 106 -46.5t117 -17.5q66 0 145.5 28t119.5 72q68 73 68 257q0 226 -92 379q-12 20 -17.5 27.5t-19 15.5t-32.5 8q-50 0 -107 -61q-76 47 -140 47q-59 0 -104.5 -43t-71 -104.5 t-42 -141t-21.5 -141t-5 -114.5zM413 521q0 22 15.5 37.5t36.5 15.5q22 0 37.5 -15.5t15.5 -37.5t-15.5 -37t-37.5 -15q-21 0 -36.5 15t-15.5 37zM469 539q0 -12 12 -12q5 0 8.5 3.5t3.5 8.5t-3.5 9t-8.5 4q-12 0 -12 -13zM563 479l2 2l-1 -3zM568 484l52 52l51 -52 q-22 -7 -50 -7q-29 0 -53 7zM570 462q27 -5 50 -5q22 0 49 5l-49 -49zM675 478v3l1 -2zM702 521q0 22 15.5 37.5t37.5 15.5t37.5 -15.5t15.5 -37.5t-15.5 -37t-37.5 -15t-37.5 15t-15.5 37zM758 539q0 -5 4 -8.5t8 -3.5q5 0 9 3.5t4 8.5q0 13 -13 13q-5 0 -8.5 -4t-3.5 -9z " />
<glyph unicode="Q" horiz-adv-x="869" d="M3 -163v957q121 21 297 21q140 0 235.5 -24t165.5 -77q165 -125 165 -370q0 -260 -161 -395q-148 -126 -451 -126q-143 0 -251 14zM223 -1q19 -4 77 -4h4q153 0 240 85q89 86 89 256q0 154 -81.5 232t-228.5 78q-66 0 -100 -9v-638z" />
<glyph unicode="R" d="M0 -46q0 55 39 94t94 39t94 -39t39 -94q0 -56 -39 -94.5t-94 -38.5t-94 39t-39 94zM0 289v191q179 0 331 -88.5t240.5 -240.5t88.5 -331h-192q0 194 -137 331q-138 138 -331 138zM0 628v192q203 0 388 -79.5t319 -213.5t213.5 -319t79.5 -388h-192q0 164 -64 314 t-172.5 258t-258 172t-313.5 64z" />
<glyph unicode="S" horiz-adv-x="986" d="M0 547q0 113 80 193t193 80q78 0 145 -42q36 7 80 7q195 0 333 -138t138 -332q0 -49 -11 -101q28 -59 28 -121q0 -113 -80 -193t-193 -80q-68 0 -129 32q-45 -8 -86 -8q-194 0 -332 138t-138 333q0 47 9 94q-37 65 -37 138zM221 181q0 -41 30 -85q71 -104 246 -104 q50 0 96.5 11t87.5 34t66 63.5t25 94.5q0 58 -29.5 98t-73.5 58t-95.5 32.5t-95.5 23t-73.5 26t-29.5 44.5q0 33 36.5 49t74.5 16q40 0 66 -12.5t38 -30t21 -35t24.5 -30t39.5 -12.5q27 0 47.5 19t20.5 46t-15 54q-30 55 -95 80t-138 25q-46 0 -89 -9t-83 -29t-64.5 -56.5 t-24.5 -86.5q0 -66 40 -106.5t97 -57t114.5 -28.5t97.5 -33.5t40 -58.5q0 -29 -23 -49t-50.5 -27t-56.5 -7q-38 0 -64.5 10.5t-38.5 27t-22.5 35t-18 35t-22.5 27t-37 10.5q-28 0 -48.5 -17t-20.5 -45z" />
<glyph unicode="T" horiz-adv-x="1230" d="M0 -83q30 -3 60 -3q176 0 314 108q-82 1 -147 50t-89 125q20 -4 47 -4q35 0 67 9q-88 17 -145.5 86.5t-57.5 160.5v3q53 -30 115 -31q-52 34 -82.5 89.5t-30.5 120.5q0 68 35 127q94 -117 229.5 -186.5t290.5 -77.5q-7 33 -7 58q0 104 74 178t179 74q109 0 184 -80 q87 18 160 62q-28 -91 -110 -140q73 9 144 40q-48 -75 -125 -131v-33q0 -101 -29.5 -202.5t-90 -194t-144.5 -164.5t-201.5 -114.5t-252.5 -42.5q-209 0 -387 113z" />
<glyph unicode="U" horiz-adv-x="859" d="M-15 103q0 54 6 162q4 53 38 86.5t87 36.5q100 5 301 5t301 -5q53 -3 87 -36.5t38 -86.5q5 -90 5 -162t-5 -162q-4 -53 -38 -86.5t-87 -36.5q-100 -5 -301 -5t-301 5q-53 3 -87 36.5t-38 86.5q-6 108 -6 162zM52 244h61v-326h59v326h61v55h-181v-55zM117 847h60l38 -152 h4l36 152h60l-46 -148q-23 -73 -23 -75v-158h-59v151q-2 14 -5.5 25.5t-9 26.5t-8.5 25zM233 -38q0 -48 36 -48q32 0 61 35v-31h52v281h-52v-214q-21 -21 -31 -21q-14 0 -14 19v216h-52v-237zM312 537v146q0 34 22 52.5t56 18.5q33 0 53.5 -20t20.5 -53v-145 q0 -36 -20 -56.5t-56 -20.5q-35 0 -55.5 21.5t-20.5 56.5zM366 530q0 -23 22 -23q23 0 23 25v153q0 9 -7 15t-16 6t-15.5 -5.5t-6.5 -14.5v-156zM433 -82h53v21q20 -25 50 -25q47 0 47 62v156q0 71 -51 71q-25 0 -46 -27v123h-53v-381zM486 -29v176q11 11 22 11q22 0 22 -28 v-148q0 -24 -19 -24q-14 0 -25 13zM509 510v237h52v-215q0 -19 14 -19q13 0 31 21v213h52v-281h-52v31q-29 -35 -61 -35q-36 0 -36 48zM623 -3q0 -38 19 -62.5t57 -24.5q78 0 78 87v21h-54q0 -2 0.5 -13.5t-0.5 -16.5t-2.5 -13.5t-6.5 -12t-14 -3.5q-23 0 -23 40v53h100v72 q0 38 -18.5 60t-56.5 22q-36 0 -57.5 -23t-21.5 -59v-127zM677 96v30q0 31 23 31t23 -31v-30h-46z" />
<glyph unicode="V" horiz-adv-x="1146" d="M0 548q55 65 110 116t95.5 77.5t72.5 43t48 21.5l17 4q12 2 24 2q19 0 35 -6q26 -10 42.5 -34.5t29 -55t21.5 -72t15 -77.5t13.5 -79.5t14.5 -70.5q32 -125 51.5 -177.5t41.5 -52.5q24 0 66.5 55.5t93.5 151.5q26 48 26 91q0 13 -2 23q-9 52 -51 65q-11 4 -24 4 q-35 0 -83 -26q22 130 134 209q85 60 174 60q12 0 24 -1q102 -8 139 -90q18 -38 18 -88q0 -29 -6 -61q-18 -102 -69.5 -208t-113 -187.5t-132.5 -155t-123.5 -117t-90.5 -68.5q-42 -24 -78.5 -24t-69.5 21t-56 48t-38 57q-18 38 -97.5 298.5t-96.5 280.5q-1 2 -4 4 t-13.5 4.5t-24 0t-36.5 -14t-50 -32.5z" />
<glyph unicode="W" horiz-adv-x="1233" d="M0 -73l105 371q35 20 85.5 31t83.5 13l34 1q50 0 104 -10q101 -20 144 -61l-104 -370q-36 28 -79.5 45.5t-68.5 20.5l-26 4q-34 3 -65 3q-16 0 -42.5 -1.5t-83.5 -13.5t-87 -33zM126 404l105 371q35 20 86 31.5t84 12.5l33 1q51 0 104 -10q101 -20 144 -61l-104 -371 q-36 28 -79.5 45.5t-68.5 20.5l-26 4q-35 3 -64 3q-16 0 -42.5 -1.5t-84 -13t-87.5 -32.5zM557 -109l104 371q37 -28 80.5 -45.5t68.5 -20.5l25 -4q34 -3 65 -3q16 0 42.5 1.5t84 13t86.5 32.5l-104 -371q-35 -20 -86 -31t-84 -12l-33 -2q-51 0 -104 10q-101 20 -145 61z M677 366l104 370q37 -28 80.5 -45.5t68.5 -20.5l25 -4q34 -3 65 -3q16 0 42.5 1.5t83.5 13t87 32.5l-104 -370q-35 -20 -86 -31.5t-85 -12.5l-33 -2q-52 0 -103 11q-101 19 -145 61z" />
<glyph unicode="X" horiz-adv-x="899" d="M-50 120h219l173 286l-130 229h-219l130 -229zM312 210l346 608h232l-345 -608l222 -392h-232z" />
<glyph unicode="Y" horiz-adv-x="1379" d="M0 694l6 -19q4 -6 7.5 -10t5.5 -5l2 -2l19 -10h111l287 -344q11 -12 11 -25v-192q0 -8 -2.5 -12t-5.5 -5h-3q-112 0 -142 -3q-10 0 -10 -9v-55h516v57q0 3 -2.5 5t-4.5 2h-2h-144q-9 0 -9 15v202q-1 3 1.5 7t5.5 7l3 3q11 11 264 249h133q9 0 18 7l17 19q6 7 6 18v14 q-1 3 -3 4.5t-3 1.5h-2h-436l-7 -6q-1 -6 1.5 -12.5t5.5 -9.5l2 -4l23 -23l18 -7h115l-207 -195l-228 291h41q13 -1 22 4l68 21q1 0 3 1t4.5 5t2.5 9v14q0 3 -2 5t-4 2h-3h-489q-8 -1 -10 -7v-8zM1190 803l185 -7l-83 -567l-61 3zM1203 40l4 110l110 -4l-4 -110z" />
<glyph unicode="Z" horiz-adv-x="870" d="M0 19q0 22 43 51q7 15 16.5 35.5t16 33t6.5 15.5q0 1 2.5 13.5t7 32t9.5 42.5t12.5 52t15.5 54q13 41 31 75t29 47.5t17 18.5q10 8 3 11q-9 6 -22 21.5t-29 60.5q-11 32 -11 70q0 14 2 29q2 16 7 3q3 -8 6 -25q4 -33 26.5 -74.5t60.5 -56.5q1 0 19.5 7t82 19t156.5 19 q1 37 7 76q-7 5 -11 13.5t-5 14.5l-1 6q-8 -14 -20 -13q-8 1 -8 33q0 17 2 43q1 20 18.5 32t32.5 13q2 1 5.5 2.5t13 3.5t17.5 2q14 15 45 19q19 3 35 3q11 0 20 -1l23 -3q11 1 22 1l40 -4q31 -8 47 -17l15 -9h4q27 0 41 -27q10 -17 16 -41q2 -10 3 -20q0 -14 -5 -29h-4 q-5 5 -10 17q-4 -12 -9.5 -21.5t-8.5 -12.5l-4 -4v-6q0 -44 -27 -102q-3 -8 2 -21q7 -16 23 -86q16 -66 15 -95v-3q-1 -31 -14.5 -65.5t-27.5 -48.5q1 -5 0 -10q0 -32 -21 -72q-7 -11 -17.5 -44t-14.5 -53q-5 -26 -5 -42q0 -14 4 -20q1 -1 10 -12.5t14.5 -20.5t4.5 -15 q-1 -9 -16.5 -18.5t-25.5 -9.5q-12 0 -27 7t-20 19q-6 19 -6 38q0 14 3 28q5 19 11 49q6 29 12 87q2 20 2 38q0 31 -7 51q-5 -2 -15 -5.5t-41.5 -9t-65.5 -5.5q-6 -30 -13 -57t-11 -38l-5 -12q-5 -8 -5 -113q0 -41 14 -103q9 -6 13 -14t4 -13v-5q-2 -13 -15.5 -20.5 t-29.5 -7.5t-31 11t-15 28q0 3 2 49q1 28 0 48v23q-4 78 -7 91q-26 97 -27 143q-7 0 -13 5l-53 -56q1 -5 4 -15.5t5 -18.5t2 -11q0 -8 14 -14q12 -5 25.5 -15t12.5 -20q-1 -12 -23 -14h-6q-20 0 -40 9q-2 1 -6.5 11t-9.5 24.5t-9.5 28.5t-8.5 27t-5 15q-5 21 -1 29 q15 41 15 60v4q-1 14 -22.5 32t-39.5 18q-7 0 -16.5 -5t-16 -10.5t-19.5 -16t-16 -13.5q-15 -11 -38 -32t-24 -22q-5 -3 -37 -61t-41 -81q0 -1 -2.5 -9.5t-4.5 -15t-7.5 -16t-11.5 -16t-15.5 -10.5t-21.5 -4q-22 1 -22 19z" />
<glyph unicode="[" horiz-adv-x="999" d="M0 297q0 75 23 155.5t62 144.5q62 104 182.5 163.5t248.5 59.5q130 0 249.5 -81.5t182.5 -201.5q50 -86 50 -214q0 -150 -71 -266t-192 -177t-270 -60q20 36 61 109.5t73.5 130.5t64.5 108l1 2q3 5 12 18.5t12.5 19.5t9.5 17t9.5 21t5.5 21q6 24 6 48q0 80 -48 142 l275 81q-285 0 -428 -1q-7 1 -22 1q-99 0 -165.5 -74t-55.5 -173q-2 9 -2 28q0 44 15 77l-204 201l198 -341q19 -72 79.5 -117.5t134.5 -45.5q17 0 33 3l-66 -276q-115 0 -223 71t-175 176q-66 102 -66 230zM312 316q0 -77 54.5 -131.5t130.5 -54.5t130.5 54.5t54.5 131.5 q0 76 -54 130.5t-131 54.5t-131 -54.5t-54 -130.5z" />
<glyph unicode="\" horiz-adv-x="831" d="M0 -155q0 27 31 27q12 0 21 0.5t28.5 7t32 17.5t23 35t10.5 57v614q0 127 -92 135q-15 1 -21.5 6.5t-7 10t-0.5 15.5q-2 25 23 25q4 0 62 -1.5t137 -3t135 -1.5q115 0 196.5 5.5t121 10.5t52.5 5q31 0 31 -31q0 -3 -6 -25.5t-6 -41.5q0 -16 3.5 -47t3.5 -44 q0 -18 -12 -27.5t-24 -9.5q-20 0 -21 28q0 4 0.5 14t0 14.5t-3 14.5t-7.5 15t-15 13t-24 12.5t-36 10t-50.5 8.5t-67 5t-85.5 2q-80 0 -115.5 -7.5t-43 -20t-7.5 -42.5q0 -29 0.5 -134.5t0.5 -115.5q0 -19 6.5 -26.5t22.5 -7.5h233q38 0 65.5 21.5t30.5 66.5q1 16 5 24 t8.5 9.5t14.5 1.5q14 0 22.5 -11.5t6.5 -33.5q0 -7 -4.5 -46t-4.5 -65q0 -25 4.5 -67t4.5 -57q0 -26 -22.5 -29.5t-29.5 23.5q-4 17 -6.5 24.5t-11.5 24t-20.5 24.5t-33.5 15.5t-51 7.5h-207q-18 0 -26 -11t-8 -38v-265q0 -43 22 -69t85 -26q5 0 50 -0.5t63 0t60 3t65.5 7.5 t52.5 15.5t47 24.5q24 19 34.5 46.5t19.5 80.5q4 19 26 18q28 0 37 -32q3 -11 2 -24q-1 -12 -16.5 -63.5t-15.5 -74.5q0 -6 0.5 -21.5t0.5 -23t-2 -18t-8 -15t-15 -4.5q-2 0 -33.5 7t-103.5 7q-66 0 -322 -1.5t-285 -1.5q-19 0 -25 5.5t-6 18.5z" />
<glyph unicode="]" horiz-adv-x="1040" d="M2 69v576q0 1 3 19l339 -290l-338 -325q-4 14 -4 20zM47 704q7 3 17 3h913q9 0 18 -3l-340 -291l-45 -36l-89 -73l-89 73l-45 36zM48 10l341 327l132 -107l132 107l341 -327q-8 -3 -17 -3h-913q-8 0 -16 3zM698 374l338 290q3 -9 3 -19v-576q0 -9 -3 -20z" />
<glyph unicode="^" horiz-adv-x="1106" d="M0 207v151q0 10 7 17.5t18 7.5h265l-115 -201h-150q-11 0 -18 7t-7 18zM122 -37l66 -38zM132 6.5q-3 10.5 2 19.5l304 528q5 9 15 11.5t19 -2.5l65 -37q10 -5 12.5 -15.5t-2.5 -19.5l-303 -528q-5 -9 -15.5 -11.5t-19.5 2.5l-65 38q-9 4 -12 14.5zM440 182l115 201h67 l94 -201h-276zM518 807q1 9 6 12q10 5 35.5 -31t71.5 -116t62 -105q28 -44 75.5 -130.5t91 -169t43.5 -83.5q11 -19 -2 -36t-31 -24q-18 -8 -24 -9t-30 7q-30 15 -190 393q-5 11 -13.5 30.5t-17 38t-18.5 42t-18.5 44t-17 42t-13.5 39t-8 32.5t-2 24zM846 383h235 q10 0 17.5 -7.5t7.5 -17.5v-151q0 -10 -7.5 -17.5t-17.5 -7.5h-133q-4 16 -8 23l-24 46q-64 121 -70 132zM859 66.5q3 10.5 13 15.5l37 19q10 5 21 1.5t16 -13.5l31 -60q12 -24 -10 -39l-27 -16q-10 -5 -21 -2.5t-17 12.5l-40 62q-6 10 -3 20.5zM935.5 -78q0.5 16 4 21 t12.5 14l24 9q61 12 72 -70q3 -32 -1 -76q-4 12 -44 29.5t-55 38.5q-13 18 -12.5 34z" />
<glyph unicode="_" horiz-adv-x="1084" d="M-1 2v89v54v207h140v-207h805v207h141v-207v-54v-89h-1086z" />
<glyph unicode="`" d="M0 298q0 141 67 260.5t182 189t251 69.5t251 -69.5t182 -189t67 -260.5q0 -4 -0.5 -10t-0.5 -10q-8 208 -152.5 353t-346.5 145t-346.5 -145t-152.5 -353q0 4 -0.5 10t-0.5 10zM183 299q0 136 93 232.5t224 96.5t224 -96.5t93 -232.5q0 -3 -0.5 -10t-0.5 -10 q-8 129 -99 219t-217 90t-217 -90t-99 -219q0 3 -0.5 10t-0.5 10zM349 104q0 33 4.5 59t10.5 43t18.5 29t23 18t28.5 9.5t31 4t35 0.5t35 -0.5t31 -4t28.5 -9.5t23 -18t18.5 -29t10.5 -43t4.5 -59q0 -118 -44.5 -202.5t-106.5 -84.5t-106.5 84.5t-44.5 202.5zM396 384 q0 44 30.5 76t73.5 32t73.5 -32t30.5 -76t-30.5 -76t-73.5 -32t-73.5 32t-30.5 76z" />
<glyph unicode="a" horiz-adv-x="1099" d="M1 44q5 8 16 1q250 -145 544 -145q196 0 387 73q5 2 14.5 6t13.5 6q15 6 23.5 -6t-5.5 -22q-18 -13 -46 -30q-86 -51 -192 -79t-207 -28q-156 0 -295 54.5t-249 153.5q-6 5 -6 10q0 3 2 6zM302 329q0 69 34 118t93 74q54 23 133 33q27 3 88 8v17q0 64 -14 86 q-21 30 -66 30h-8q-33 -3 -57 -21t-31 -50q-4 -20 -20 -23l-115 14q-17 4 -17 18q0 3 1 7q17 89 83.5 132t155.5 48h25q114 0 178 -59q10 -10 18.5 -21.5t13.5 -20.5t9 -26t6 -23.5t3 -28t1 -25.5v-30v-28v-184q0 -26 7.5 -47.5t14.5 -31t23 -30.5q6 -9 6 -16q0 -8 -8 -14 q-83 -72 -90 -78q-12 -9 -29 -2q-14 12 -24.5 23t-15 16t-14.5 19.5t-14 19.5q-56 -61 -110 -76q-34 -10 -84 -10q-77 0 -126.5 47.5t-49.5 134.5zM474 349q0 -39 19.5 -62.5t52.5 -23.5q3 0 8.5 1t7.5 1q42 11 65 54q11 19 16.5 41.5t6 36.5t0.5 46v25q-58 0 -88 -8 q-88 -25 -88 -111zM894 27q2 4 6 8q25 17 48 23q38 10 74 11q10 1 19 -1q45 -4 54 -15q4 -6 4 -18v-7q0 -35 -19 -82.5t-53 -76.5q-5 -4 -9 -4q-2 0 -4 1q-6 3 -3 11q37 87 37 121q0 11 -4 16q-10 12 -56 12q-17 0 -40 -2q-25 -3 -46 -6q-6 0 -8 2t-1 4q0 1 1 3z" />
<glyph unicode="b" horiz-adv-x="1314" d="M-2 438q0 55 38.5 94t93.5 39q47 0 83.5 -29.5t46.5 -74.5l502 -202q32 19 68 19q2 0 6.5 -0.5t7.5 -0.5l110 159q1 73 53 124.5t125 51.5q74 0 126 -52t52 -126t-52 -126t-126 -52l-170 -124q-5 -51 -43 -85.5t-89 -34.5q-48 0 -84 30t-46 75l-502 201q-32 -19 -68 -19 q-55 0 -93.5 39t-38.5 94zM33 438q0 -40 28.5 -68.5t68.5 -28.5q9 0 21 2l-41 16v1q-28 13 -40 42q-6 14 -6 28q0 15 6 30q12 30 40 42q15 7 31 6q13 0 27 -5v1l49 -20q-29 52 -87 52q-40 0 -68.5 -28.5t-28.5 -69.5zM743 105q29 -52 87 -52q40 0 69 28.5t29 69.5 q0 40 -28.5 68.5t-69.5 28.5q-14 0 -21 -2l40 -16q30 -12 43 -42q7 -15 7 -30q0 -14 -6 -29q-12 -31 -42 -43q-15 -6 -30 -6q-14 0 -29 6q-8 3 -24.5 9.5t-24.5 9.5zM1013 440q0 -49 35 -84t84 -35q50 0 85 35t35 84t-35 84t-85 35q-49 0 -84 -35t-35 -84zM1038 441 q0 -40 27.5 -68t67.5 -28q39 0 67 28t28 68q0 39 -28 67t-67 28q-40 0 -67.5 -28t-27.5 -67z" />
<glyph unicode="c" horiz-adv-x="1107" d="M-2 251q0 104 73.5 178t176.5 74l1 -1q0 3 -0.5 7t-0.5 6q0 118 82.5 201t199.5 83q103 0 181 -66t96 -166h17q117 0 199.5 -83t82.5 -201t-82.5 -201t-199.5 -83q-8 0 -12 1v-1h-555h-9h-9h-5v1q-99 5 -167.5 78t-68.5 173z" />
<glyph unicode="d" horiz-adv-x="1013" d="M-12 286l214 163l-214 162l311 203l203 -174l208 174l302 -193l-198 -165l198 -170l-307 -185l-203 156l-203 -156zM201 35v57l94 -55l203 155l1 -1v-355zM206 451l294 -185l296 196l-294 169zM499 -164l1 355l2 1l202 -155l100 60v-63z" />
<glyph unicode="e" horiz-adv-x="1407" d="M0 181q0 31 5 53.5t21.5 46.5t46.5 38.5t83.5 24t128.5 9.5q88 0 148 -13q39 -8 58 -18v-161h-293q0 -21 2 -33.5t9 -30.5t26.5 -27t49.5 -9q85 0 85 61h63h2h56v-89q-27 -13 -56 -19q-68 -15 -150 -15q-92 0 -151 12.5t-87 39t-37.5 56t-9.5 74.5zM198 215h178 q0 18 -1.5 26.5t-8.5 23.5t-27.5 22t-53.5 7q-31 0 -50.5 -7.5t-26.5 -23t-8.5 -24t-1.5 -24.5zM491 33v89h78q-1 -51 -74 -87q-2 -2 -4 -2zM491 33q2 0 4 2q73 36 74 87h-78v39h81q1 12 1 23q0 45 -13 76q-16 39 -69 62v183h107v-203h2q31 44 88 44q43 0 69 -26 q-40 -29 -40 -102q0 -104 76 -122q-1 -31 -5.5 -54t-15.5 -47t-32.5 -36.5t-53.5 -12.5q-64 0 -91 50h-1v-42h-103v79zM491 161v161q53 -23 69 -62q13 -31 13 -76q0 -11 -1 -23h-81zM598 150q0 -77 8.5 -107.5t35.5 -30.5q28 0 37 30.5t9 107.5v5q0 35 -1 51.5t-5 37 t-13.5 28.5t-26.5 8q-16 0 -25.5 -8.5t-13 -29.5t-4.5 -38t-1 -54zM717 218q0 73 40 102q17 -18 26 -53t10 -55.5t0 -63.5v-52q-76 18 -76 122zM725 377q0 69 40 94q34 26 101 26q4 0 49 -3l107 -218v-102q0 -14 2 -39t2 -34h-100l-5 52h-2q-33 -58 -100 -58q-18 0 -26 1v52 q0 43 -0.5 63.5t-9.5 55.5t-26 53q38 29 135 29h24v31q0 29 -8.5 43t-35.5 14q-26 0 -33 -15.5t-7 -44.5h-107zM822 223q0 -62 41 -62q13 0 22.5 4.5t15.5 14t9.5 18t4.5 24t1.5 23.5t0 24t-0.5 20q-4 0 -17 -0.5t-16.5 -1l-14 -2t-14 -3t-10.5 -5t-9.5 -8t-6.5 -11 t-5 -15.5t-1 -20zM889 546h154l100 -232l109 232h143l-189 -359v-190h-141v190l-43 89v91q0 55 -21.5 86.5t-85.5 40.5zM915 494q64 -9 85.5 -40.5t21.5 -86.5v-91z" />
<glyph unicode="f" horiz-adv-x="817" d="M280 283v191h154v96q0 104 67.5 177t163.5 73h153v-191h-153q-15 0 -27 -16.5t-12 -40.5v-98h192v-191h-192v-463h-192v463h-154z" />
<glyph unicode="g" horiz-adv-x="939" d="M0 -27q0 -63 62 -108t150 -45t150.5 45t62.5 108q0 64 -62.5 109t-150.5 45q-1 0 -3 -0.5t-3 -0.5q-24 22 -24 47.5t24 53.5q71 4 120 55t49 121q0 28 -7 50q28 5 44 14v115q-48 -32 -109 -32h-7q-46 31 -101 31q-75 0 -128 -52t-53 -126q0 -47 24 -87t64 -64 q-28 -36 -28 -74q0 -36 26 -75q-46 -21 -73 -55t-27 -75zM121 405q0 33 21.5 56.5t50.5 23.5q30 0 51 -23.5t21 -56.5t-21 -56.5t-51 -23.5q-29 0 -50.5 23.5t-21.5 56.5zM124 -27q0 27 25.5 45.5t62.5 18.5t63 -18.5t26 -45.5q0 -26 -26 -45t-63 -19t-62.5 19t-25.5 45z M455 739q0 34 23.5 57.5t57.5 23.5t58 -23.5t24 -57.5t-24 -58t-58 -24t-57.5 24t-23.5 58zM474 92v479h134v-479h-134zM655 469h55v-284v-1q4 -30 19.5 -51.5t34.5 -31.5t37.5 -16t30.5 -7h13h7q27 0 48 8q23 8 30 16l7 9l2 99q-42 -13 -65 -13q-5 0 -9 1q-23 3 -27 16 l-4 13q0 3 -1 4v238h91v102h-91v93h-123v-93h-55v-102z" />
<glyph unicode="h" horiz-adv-x="866" d="M0 -196v496v496l501 -496zM0 -196l501 496l134 -133l-202 -117l-433 -250v4zM0 796v4l433 -250l202 -117l-134 -133zM501 300l134 133l231 -133l-231 -133z" />
<glyph unicode="i" d="M0 320q0 136 67 251t182 182t251 67t251 -67t182 -182t67 -251t-67 -251t-182 -182t-251 -67t-251 67t-182 182t-67 251zM100 320q0 -166 117 -283t283 -117t283 117t117 283t-117 283t-283 117t-283 -117t-117 -283zM283 144q0 -31 21.5 -52.5t52.5 -21.5q33 0 57 24 t24 57v8v261l200 37v-208q-15 5 -28 5q-33 0 -57 -24t-24 -57q0 -31 21 -52.5t52 -21.5t55.5 23t25.5 54v4v8v382l-290 -50v-300q-15 5 -28 5q-34 0 -58 -24t-24 -57z" />
<glyph unicode="j" horiz-adv-x="764" d="M0 -183v1000h764v-817l-571 3v-186h-193zM191 176h399v450h-399v-450z" />
<glyph unicode="k" d="M0 253v67v67t2.5 59t7 61.5t14 53t23.5 55.5t35.5 46.5t50.5 47.5q146 110 356 110h11h5v-777h124v208q7 -11 39 -63.5t51 -79.5q29 -40 63.5 -53t91.5 -13h36v118q-45 0 -63 7t-42 41q-14 18 -37 56.5t-26 43.5l171 238h-148l-136 -189v453q135 -22 238 -100 q29 -22 50.5 -47.5t35.5 -46.5t23.5 -55.5t14 -53t7 -61.5t2.5 -59v-67v-67t-2.5 -59t-7 -61.5t-14 -53t-23.5 -55.5t-35.5 -46.5t-50.5 -47.5q-146 -110 -367 -110t-367 110q-29 22 -50.5 47.5t-35.5 46.5t-23.5 55.5t-14 53t-7 61.5t-2.5 59zM81 104q66 -67 192 -67 q80 0 137.5 41t57.5 118q0 51 -18 84.5t-45 45.5t-58.5 19.5t-58.5 9t-45 11.5t-18 30q0 47 70 46q57 0 87 -29l78 78q-60 60 -170 60q-78 0 -131.5 -41.5t-53.5 -117.5q0 -51 20.5 -83.5t51.5 -44.5t62.5 -17t59.5 -9t37 -14q10 -11 10 -30q0 -46 -72 -46q-77 0 -113 36z " />
<glyph unicode="l" horiz-adv-x="1332" d="M-1 320q0 164 116 280t280 116q124 0 219.5 -63.5t146.5 -180.5q15 -36 129 -300q21 -48 37.5 -73.5t49 -45t79.5 -21.5h7q67 0 111 36q46 38 47 96q0 27 -8 45t-29.5 32t-40.5 21.5t-59 20.5q-125 41 -180 89.5t-55 135.5q0 91 57.5 145.5t156.5 54.5q127 0 191 -115 l-84 -43q-45 62 -112 62q-46 0 -76.5 -28.5t-30.5 -72.5q0 -13 2 -24.5t8.5 -20.5t12 -16t17.5 -14.5t20 -11.5t25 -10.5t26.5 -9.5t31.5 -10t33 -10q108 -36 154.5 -84t46.5 -140q0 -100 -76 -166q-75 -65 -186 -65h-3q-100 0 -161 46.5t-103 140.5l-14 33l-127 288 q-33 77 -104.5 124t-158.5 47q-119 0 -203.5 -84.5t-84.5 -203.5t84.5 -203.5t203.5 -84.5q82 0 150 42.5t105 112.5l51 -118q-55 -68 -135 -106.5t-171 -38.5q-164 0 -280 116t-116 280z" />
<glyph unicode="m" horiz-adv-x="1210" d="M7 -117v897h185l9 -8h825l9 8h174v-900h-171v7h-855v-4h-176zM183 15v-80h855v74l-345 259l-79 -65l-86 70zM183 75l307 229l-307 252v-481zM266 716l348 -298l347 298h-695zM731 299l307 -230v484z" />
<glyph unicode="n" d="M0 496l316 323v-123l301 -277l187 46l-195 -208l391 -438l-444 392l-188 -192l30 169l-255 316z" />
<glyph unicode="o" horiz-adv-x="1083" d="M0 173q-1 63 24.5 116.5t67 89t92 63t101 43t92.5 25.5t68 13l26 3v-123q-57 -4 -104.5 -19.5t-77.5 -36.5t-53 -45.5t-35 -48t-19 -42.5t-8 -31l-2 -12q-3 -15 -3 -30q0 -22 7 -42q12 -34 38 -58t59 -44.5t68 -33t64 -21.5t47 -13l19 -3v-103q-97 10 -175.5 35 t-126.5 56.5t-83 67.5t-51 70.5t-24.5 62t-9.5 44.5zM510 -180v902l142 98v-922zM686 411h5q38 -1 77 -15q42 -16 64 -31l21 -16l-83 -34l313 -78v245l-107 -61q-40 43 -112.5 69t-125.5 31l-52 5v-115z" />
<glyph unicode="p" d="M0 -47v734q0 55 39 94t94 39h734q55 0 94 -39t39 -94v-734q0 -55 -39 -94t-94 -39h-734q-55 0 -94 39t-39 94zM38 -19q0 -51 36 -87t87 -36h678q51 0 87 36t36 87v678q0 51 -36 87t-87 36h-678q-51 0 -87 -36t-36 -87v-678zM239 13v30h49q28 0 44 18.5t18 36.5l1 19v6v29 v377q0 35 -15 54.5t-30 21.5l-15 2h-50v32h349q46 0 80.5 -15t52 -36.5t28 -42.5t13.5 -36l2 -15v-62q0 -31 -9 -55.5t-23.5 -39.5t-32 -26.5t-35.5 -16.5t-32.5 -7.5t-23.5 -2.5l-9 -1h-143v-168q0 -31 17 -48.5t35 -19.5l17 -2h47v-32h-335zM457 338h109q4 0 10 0.5 t21.5 6t27.5 14.5t21.5 28.5t9.5 46.5l-1 61q0 4 -0.5 10t-6 22.5t-14.5 29.5t-29.5 25t-47.5 14h-100v-258z" />
<glyph unicode="q" horiz-adv-x="889" d="M0 366q0 122 59.5 226t161.5 164.5t223 60.5q184 0 314.5 -132t130.5 -319q0 -119 -57 -220.5t-154 -162.5q1 -2 3.5 -6.5t11.5 -16t21 -22t33 -21.5t45 -17v-76q-36 -7 -67 -7q-50 0 -85 18q-56 29 -91 94q-48 -13 -105 -13q-120 0 -222.5 60.5t-162 164t-59.5 225.5z M221 307q0 -116 66.5 -198.5t160.5 -82.5q26 0 52 8q-2 3 -5.5 8.5t-14.5 18.5t-23.5 23.5t-31 19.5t-36.5 10v79v9q10 1 20 1q119 0 203 -90q63 81 63 194v116q0 116 -66.5 198.5t-160.5 82.5t-160.5 -82.5t-66.5 -198.5v-116z" />
<glyph unicode="r" horiz-adv-x="1201" d="M0 320q0 139 72 254.5t191.5 180.5t257.5 65q86 0 162 -25v-302q-64 35 -132 35q-92 0 -162 -49q-45 -33 -80.5 -82.5t-35.5 -95.5q0 -90 57.5 -141t148.5 -51q78 0 151.5 41.5t108.5 108.5q21 37 21 50q1 67 1 143t-0.5 169t-0.5 144q20 -10 119 -77q135 -92 289 -92 q20 0 26.5 -7.5t6.5 -29.5q0 -51 -53 -100.5t-110 -69.5q4 -31 4 -69q0 -139 -72 -254.5t-191.5 -180.5t-257.5 -65t-257.5 65t-191.5 180.5t-72 254.5z" />
<glyph unicode="s" horiz-adv-x="1153" d="M0 141q0 16 3.5 44t9.5 31q6 -3 10.5 -32.5t4.5 -42.5q0 -14 -4.5 -42.5t-10.5 -31.5q-13 7 -13 74zM64 141q0 25 5 74t6 61q0 6 6 6q4 0 6 -6q12 -129 12 -135q0 -24 -5.5 -71t-6.5 -59q-2 -7 -6 -7q-6 0 -6 7q-1 11 -6 58.5t-5 71.5zM145 141q0 24 5 73.5t5 54.5 q0 9 7 9q8 0 8 -9q11 -113 11 -128t-11 -136q0 -8 -8 -8q-7 0 -7 8q0 7 -5 58.5t-5 77.5zM237 141q0 38 1.5 80.5t4 95t3.5 81.5q0 10 9 10q10 0 10 -10q1 -16 5.5 -111.5t4.5 -145.5q0 -26 -5 -77t-5 -58q0 -10 -10 -10q-9 0 -9 10q-9 132 -9 135zM331 141q0 55 3 159.5 t4 128.5q2 12 12 12t12 -12q1 -32 4.5 -133t3.5 -155q0 -25 -3.5 -72t-4.5 -61q-2 -12 -12 -12t-12 12q0 11 -3.5 59t-3.5 74zM426 141q0 40 1 85t2.5 100t2.5 85q2 15 14 15t14 -15q1 -30 2.5 -85t2.5 -100t1 -85q0 -2 -6 -131v1q-2 -15 -14 -15t-14 14q-6 129 -6 131z M521 140q0 3 6 351q2 18 16 18t16 -18q6 -348 6 -351q0 -1 -6 -127q-2 -17 -16 -17t-16 17q-6 126 -6 127zM601 352.5q0 82.5 1 155.5q-1 10 12.5 18t32.5 11.5t34.5 5.5t24.5 2q97 0 169 -72.5t80 -178.5q28 13 55 13q58 0 99.5 -45.5t42 -110.5t-41.5 -110.5t-100 -45.5 h-393q-6 0 -10.5 6t-4.5 13q0 55 -0.5 155.5t-0.5 183z" />
<glyph unicode="t" horiz-adv-x="616" d="M0 410v142q60 20 101 55q41 33 67 86q26 51 35 127h143v-253h237v-157h-237v-256q0 -86 9 -112q9 -24 34 -39q34 -20 76 -20q77 0 151 49v-157q-63 -31 -116 -43q-52 -12 -112 -12q-68 0 -122 17q-55 19 -89 50q-36 31 -52 68q-14 34 -14 105v350h-111z" />
<glyph unicode="u" horiz-adv-x="916" d="M2 455q4 36 15.5 63t25.5 40t28 21t23 9l9 2h8q43 0 77 -36q38 -40 41 -78q3 -16 3 -33v-6q0 -20 -5.5 -53t-28 -57.5t-59.5 -32.5q-13 -3 -26 -3q-23 0 -43 10q-30 15 -45 43t-21 58q-4 17 -4 32q0 11 2 21zM66 -32q-4 18 -4 36q0 28 10 55q16 44 38.5 68t48.5 45l26 21 q2 2 26.5 22.5t53.5 51.5t49 66q18 31 50 53q33 22 72 28q9 1 17 1q31 0 66 -18q44 -23 79 -77q8 -12 23.5 -31.5t66.5 -72t106 -95.5q26 -20 39.5 -49.5t13.5 -57t-4 -52t-9 -39.5l-6 -15q-2 -6 -7.5 -15t-27.5 -29t-50 -31.5t-79 -11.5t-112 20q-36 12 -79 13h-14 q-33 0 -55 -4l-25 -4q-10 -2 -27 -5q-18 -3 -66 -8q-24 -2 -44 -2.5t-36 2.5h-3q-46 0 -80 33q-35 34 -46 68zM208 72q-2 -14 -2 -27q0 -32 12 -61q22 -43 79 -55h127v307l-57 1v-83h-68q-30 0 -53 -20.5t-30 -41.5zM232 666q0 64 31.5 109t76.5 45t76.5 -45t31.5 -109 t-31.5 -109t-76.5 -45t-76.5 45t-31.5 109zM268 23q-2 8 -2 16q0 14 6 31q10 26 39 35h55v-125h-51q-16 0 -27.5 10.5t-15.5 21.5zM455 -15q0 -18 15 -31.5t30 -18.5l15 -5h146v217h-63v-163h-60q-9 1 -14.5 6t-7.5 9l-1 4v145l-60 -1v-162zM508 657q5 48 49 97q37 41 72 41 q6 0 13 -1q43 -10 74 -58q25 -39 25 -77q0 -9 -1 -18q-9 -55 -48 -101q-34 -39 -80 -40q-7 0 -14 1q-56 8 -76 51q-15 32 -16 75q0 14 2 30zM686 367q0 150 108 150q34 0 59.5 -14.5t38 -36t18.5 -40.5t6 -33v-14v-11v-9q0 -7 -1 -22.5t-4 -25.5t-7.5 -24t-13 -23.5 t-19 -18.5t-26.5 -13.5t-35 -4.5h-6q-38 0 -63 11q-27 12 -38 36.5t-14 44t-3 48.5z" />
<glyph unicode="v" horiz-adv-x="1011" d="M0 -21v678q0 66 43 114.5t108 48.5h697q70 0 116.5 -37.5t46.5 -106.5v-59q-74 14 -111 20q-53 7 -54 7q-10 3 -29.5 10t-34 10.5t-32.5 3.5q-62 0 -132 -47q-34 -3 -95.5 -7t-112 -9t-95.5 -14h-1h-1l-1 -1h-1h-1h-1h-1l-1 -1h-1q-72 -14 -87 -26q-18 -15 -20 -71v-39 v-126l-3 -18l526 -13l80 27q-44 -79 -70 -132l-106 -47l-406 -7q-3 -3 -10 -3.5t-11 -4.5q4 -26 7 -39q12 -52 112 -59q206 -13 335 -13q38 0 120 20t127 20q65 0 111 -29v-54q0 -155 -154 -155h-723q-61 0 -97.5 48t-36.5 111zM690 525q0 14 10 24.5t24 10.5t24.5 -10.5 t10.5 -24.5t-10.5 -24t-24.5 -10t-24 10t-10 24z" />
<glyph unicode="w" d="M0 319q0 136 67 251t182 182t251 67t251 -67t182 -182t67 -251t-67 -251t-182 -182t-251 -67t-251 67t-182 182t-67 251zM39 319q0 -135 71.5 -247t188.5 -168l-220 603q-40 -89 -40 -188zM114 572h30q48 0 123 6q12 1 17.5 -8t1.5 -19t-16 -11l-53 -5l168 -499l101 302 l-72 197q-24 3 -48 5q-12 1 -16 11t1.5 19t17.5 8l121 -6q49 0 123 6q12 1 17.5 -8t1.5 -19t-16 -11l-52 -5l166 -496l46 154q36 117 36 149q0 64 -39 128q-2 3 -12.5 21t-13.5 23.5t-9 19t-8 23.5t-2 21q0 33 22.5 57.5t55.5 24.5q1 0 3 -0.5t3 -0.5q-131 121 -312 121 q-119 0 -221 -56t-165 -152zM370 -124q62 -18 130 -18q80 0 153 26l-3 6l-142 389zM732 -80q105 61 167 167.5t62 231.5q0 120 -56 221q3 -21 3 -47q0 -63 -35 -165z" />
<glyph unicode="x" horiz-adv-x="1002" d="M0 320q0 -176 109 -312q-9 25 -9 56q0 32 10 68q20 72 61.5 139.5t86 127.5t78.5 96l33 36q-147 91 -234 130q-135 -145 -135 -341zM139 -25q23 68 68.5 139t94 124t94 96.5t74.5 65.5l29 23q13 -9 34 -26t77.5 -68t102.5 -102t90.5 -121t59.5 -131q-70 -73 -164 -114 t-198 -41q-105 0 -198.5 41t-163.5 114zM176 700q139 120 325 120q185 0 324 -120q-35 20 -81 20t-87 -14.5t-77 -31.5t-58 -32l-21 -14h-1q-8 6 -22.5 15.5t-55.5 30.5t-79 33.5t-85 12.5q-1 0 -2 1q-46 0 -80 -21zM632 531q148 91 235 130q135 -145 135 -341 q0 -176 -110 -312q9 26 9 56q1 30 -9 68q-20 72 -62 139.5t-86.5 127.5t-77.5 96z" />
<glyph unicode="y" horiz-adv-x="749" d="M4 231v-13q0 -43 6 -69q5 -18 19 -25.5t29 -2.5l204 63q22 7 31 26q5 10 5 20t-5 19q-9 19 -32 26l-204 82q-14 3 -27.5 -7.5t-16.5 -30.5q-8 -36 -9 -88zM91 708q-5 8 -5 16q0 9 6 18q12 17 38 27q81 31 171 46h5q45 0 49 -38q25 -313 25 -393q0 -33 -27 -40 q-6 -2 -12 -2q-21 0 -37 25q-148 232 -213 341zM160 -57l139 166q19 21 38 21q8 0 16 -3q25 -11 25 -45q0 -5 -1 -10v-221q-2 -14 -17 -22q-9 -5 -18 -5q-8 0 -16 3q-36 6 -85 25.5t-73 37.5q-18 14 -18 30q0 11 10 23zM454 280q-6 12 -6 23q0 17 15 33l130 179q7 8 20 8 q3 0 7 -1q17 -2 29 -18q25 -26 53 -70.5t37 -73.5q3 -8 3 -15q0 -9 -4 -16q-8 -13 -23 -16l-209 -53q-8 -2 -16 -2q-23 0 -36 22zM466 155q-9 -12 -9 -24q0 -16 13 -32l114 -190q7 -9 24 -9h3q19 1 33 15q27 24 55.5 62.5t41.5 69.5q4 11 4 21q0 7 -3 13q-5 14 -19 19 l-205 70q-10 4 -19 4q-21 0 -33 -19z" />
<glyph unicode="z" horiz-adv-x="722" d="M0 46v13v82q0 6 2.5 12t4.5 9l2 2q65 77 195 230.5t195 230.5q-57 -11 -103 -14q-23 -2 -41 -1q-17 0 -31 1q-26 3 -46.5 10t-28.5 13.5t-12 12.5q-1 0 -1 1q-1 2 -2 3q-4 9 -4 24q0 7 1 15q5 49 49 110q2 2 6 6.5t6 7.5q5 5 12 5q6 0 15 -4q18 -10 20 -10 q55 -22 148 -26q22 -1 44 -1q107 0 222 24q9 2 13.5 -1.5t4.5 -8.5v-5q-1 -14 -4 -42.5t-5 -42.5q0 -4 -5 -9l-13 -13l-8 -7q-8 -9 -161 -188q-126 -146 -190 -219q-20 -24 -60 -70q-11 -13 -13 -18.5t-2 -23.5h7q65 0 144 -49q45 -29 86 -51t59 -29l19 -7q45 -12 83 -12 q65 0 110 35q5 -22 5 -45q0 -27 -7 -56q-12 -53 -50 -90q-32 -31 -77 -31q-8 0 -17 1q-64 8 -166 67q-23 13 -72.5 51t-78.5 53q-48 24 -95 31t-117 7h-31q-8 0 -12 17z" />
<glyph unicode="{" horiz-adv-x="1233" d="M-63 548q174 33 208 71q27 30 45 91q18 -23 23 -48.5t1 -39.5l-5 -13q-6 -13 -10.5 -21t-7.5 -13.5t-9.5 -11t-10 -8.5t-16 -11t-20.5 -14q-35 -27 -33.5 -62.5t30.5 -54.5q26 -16 50.5 6t52.5 78q12 25 18.5 66t19.5 73t47 59q20 16 45.5 19t50 1t51.5 0t60 23.5 t67 64.5q5 6 14 15.5t38 29t59 28t74 -1t86 -44.5q-48 21 -90 21t-67.5 -15t-43.5 -33t-26 -33l-7 -15q-15 -37 -28.5 -61.5t-23.5 -38.5t-25 -22.5t-24 -11.5t-32 -8.5t-38 -9.5q-43 -13 -50 -54q-6 -36 22 -53q32 -18 82 14q37 24 59.5 49.5t30.5 44t27.5 39.5t51.5 37 q43 21 82 28.5t83 8t67 3.5q197 32 246 114q48 79 49 130q17 -58 11.5 -104t-26.5 -80.5t-44 -57t-41 -33.5l-18 -11q-77 -40 -128.5 -55.5t-83.5 -21t-62 -21.5q-103 -55 -52 -155q21 -41 61.5 -44.5t77.5 29.5q6 5 14 14t22.5 39t15.5 61q20 -56 15.5 -96.5t-20.5 -63.5 l-15 -22q-36 -38 -60.5 -53.5t-63 -18.5t-89.5 15q-86 21 -119.5 20.5t-61.5 -17.5q-28 -16 -43 -42.5t-2 -48.5q14 -25 34 -27.5t64 21.5q39 23 66 29.5t68 8.5q87 2 139 -38q37 -24 74 -57q-40 24 -79 30.5t-66 -1t-48.5 -18t-31.5 -21.5l-10 -10q-45 -51 -75.5 -72 t-53 -20.5t-58.5 14.5q-10 4 -39.5 17t-41.5 16v110q0 121 -92 186q-59 40 -134 40q-76 0 -134 -39q-20 29 -51 33v75q0 31 -21.5 52.5t-52.5 21.5h-18zM64 -16v162q0 65 19 99q40 71 134 71q69 0 110.5 -43.5t41.5 -109.5v-135h-202v-67q0 -48 50 -48q45 0 50 49h102 q0 -62 -41 -105q-43 -43 -111 -43q-94 0 -134 71q-19 34 -19 99zM167 105h100v56q0 56 -50 56t-50 -56v-56zM429 -94q11 36 11 71q0 11 -3 20q24 -4 34 -5q62 -6 85 -46q2 -3 4.5 -9t7 -23t-0.5 -31q-31 24 -65.5 30t-53.5 -1z" />
<glyph unicode="|" horiz-adv-x="851" d="M2 -56q3 31 12 66q11 45 72 350.5t71 349.5q12 52 24 72.5t39 29.5t87 9h241q59 0 135 -1t116 -1q41 0 50 -45q10 -48 -23 -92q-30 -40 -81 -40h-401l-50 -233l352 -3q44 0 54 -45t-21 -84q-27 -33 -70 -33h-360l-48 -248h432q64 0 76.5 -43.5t-17 -87.5t-67.5 -44h-553 q-30 0 -47.5 17t-21.5 46t-1 60z" />
<glyph unicode="}" horiz-adv-x="868" d="M0 108q0 44 31.5 76t76.5 32q44 0 76 -32t32 -76q0 -46 -34 -78q65 -74 163 -74q69 0 116 41q47 42 47 106q0 39 -25 77q-23 38 -60 64q-34 23 -115 57q-75 30 -122 59q-42 27 -73 64q-30 36 -46 74q-14 39 -14 79q0 101 81 172q82 71 197 71q77 0 155 -33 q66 -28 113 -80q37 -32 37 -80q0 -45 -32 -76.5t-76 -31.5q-45 0 -76.5 31.5t-31.5 76.5q0 21 10 44q-32 16 -88 16q-69 0 -112 -31t-43 -80q0 -43 38 -76q40 -33 128 -71q92 -40 141 -73q51 -34 82 -74q33 -41 48 -85q0 -1 1 -3t1 -3q-75 -62 -75 -158q0 -53 28 -104 q-11 -13 -24 -27q-87 -82 -206 -82t-208 64t-139 194l3 1q-5 15 -5 29zM613 33q0 -52 36 -88.5t88 -36.5t88 36.5t36 88.5q0 51 -36 87.5t-88 36.5t-88 -36.5t-36 -87.5z" />
<glyph unicode="~" horiz-adv-x="664" d="M0 805h100l8 -121h10l5 3q79 133 246 133q130 0 212.5 -98.5t82.5 -253.5q0 -93 -27 -166.5t-72.5 -117.5t-101 -67t-116.5 -23q-69 0 -125.5 28.5t-86.5 79.5l-2 3h-11l-3 -7v-378h-113v761q0 88 -6 224zM119 392q0 -31 6 -55q19 -70 74 -113t126 -43q101 0 162 76.5 t61 204.5q0 119 -61 194t-157 75q-72 0 -128 -45.5t-74 -117.5q-9 -33 -9 -53v-123z" />
<glyph horiz-adv-x="951" />
<glyph horiz-adv-x="973" />
<glyph horiz-adv-x="1314" />
<glyph unicode="&#xa3;" horiz-adv-x="669" d="M2 467q-11 151 126 252q63 47 145 70q78 23 175 11t181 -59q-2 -40 0 -76q6 -119 -10 -153q-9 1 -52 14q-36 11 -66 16q-31 6 -61 8q-70 6 -99 -38q8 -44 38 -66q30 -21 82 -37q49 -14 69 -26q113 -70 139 -219v-80v-5q0 -81 -44.5 -142.5t-118.5 -92.5 q-105 -44 -244.5 -38.5t-239.5 59.5q3 41 0 79q-3 42 -2 81q2 43 12 69q18 -3 48 -11q53 -15 74 -19q165 -36 177 40q3 22 -10.5 40.5t-34.5 29.5q-28 14 -48 22q-29 12 -37 17q-44 23 -59 32q-57 34 -80 68q-54 77 -60 154z" />
<glyph unicode="&#xad;" horiz-adv-x="939" d="M-0.5 707q-0.5 11 6 20.5t13.5 16.5t23.5 15.5t27 13t33 14t34.5 14.5q54 22 97 16t54 -35q25 -67 102.5 -319.5t115.5 -361.5q268 88 326 105q16 6 37.5 4t32.5 -23q23 -47 32.5 -98.5t0.5 -74.5q-19 -15 -59.5 -32t-75.5 -29t-89.5 -29t-73.5 -23q-10 -3 -38 -13 t-53 -18.5t-58 -19t-61 -17.5t-54 -11.5t-44.5 -3.5t-25.5 9q-18 18 -32 52t-29 87t-19 66q-42 125 -113 338.5t-104 312.5q-6 13 -6.5 24z" />
<glyph unicode="&#xc7;" horiz-adv-x="1294" d="M13 314v51q0 38 87 65t211 27t211 -27t87 -65v-51q-1 -38 -88 -64.5t-210 -26.5t-210 26.5t-88 64.5zM300 557v27q2 19 64 32.5t149 13.5t148.5 -13.5t63.5 -32.5h1v-27h-1q-2 -20 -63.5 -33.5t-148.5 -13.5t-149 13.5t-64 33.5zM511 63v59v5q4 56 117 94.5t271 38.5 t270.5 -38.5t116.5 -94.5v-4v-56v-4q-3 -55 -116 -94t-271 -39t-271 38.5t-117 94.5zM739 404v1v38v3q2 29 75.5 49t175.5 20t175.5 -20t75.5 -49v-2v-39v-1q0 -29 -73.5 -50t-177.5 -21t-177.5 21t-73.5 50z" />
<glyph unicode="&#xc9;" horiz-adv-x="1129" d="M0 644q0 20 13 33t33 13h235q16 0 28.5 -9.5t16.5 -25.5l24 -98h674l7 21q10 32 43 32q9 0 13 -2q15 -4 24 -16t9 -27q0 -5 -2 -13l-118 -393q-4 -15 -16 -24t-27 -9h-559q-16 0 -28.5 10t-16.5 25l-108 438h-199q-19 0 -32.5 13t-13.5 32zM372 466l62 -248h489l2 9 l72 239h-625zM414 -18q0 38 27.5 65t65.5 27t65 -27t27 -65t-27 -65t-65 -27t-65.5 27t-27.5 65zM479 388h166v-92h-146zM724 296l1 92h162l-24 -92h-139zM761 -18q0 38 27.5 65t65.5 27t65 -27t27 -65t-27 -65t-65 -27t-65.5 27t-27.5 65z" />
<glyph unicode="&#xd1;" horiz-adv-x="937" d="M5 -90v333l116 129h85v-64h-56l-80 -89v-245h795v245l-80 89h-56v64h85l115 -129v-333h-924zM206 229v79v64v187l151 151h372v-338v-64v-79h-523zM266 290h403v360h-252v-151h-151v-209z" />
<glyph unicode="&#xd6;" horiz-adv-x="696" d="M-10 86q0 63 28 98q23 31 74 45q-16 40 -16 59q0 33 35 70q37 35 69 35q17 0 40 -9q-48 137 -69 208q-24 81 -24 115q0 48 24 75q25 28 67 28q72 0 173 -295l17 -49q6 15 12 33q100 292 180 292q40 0 63 -27q24 -27 24 -70q0 -28 -24 -113q-21 -73 -66 -200 q57 -14 82 -54q27 -43 27 -133q0 -178 -106 -291q-108 -113 -274 -113q-66 0 -127 24q-59 21 -107 66q-51 48 -76 99q-26 54 -26 107zM55 91q0 -25 14 -59q13 -32 39 -67q41 -53 97 -81q57 -28 129 -28q129 0 217 97q87 96 87 243q0 46 -6 71q-5 22 -19 34q-27 23 -106 40 q-79 18 -168 18q-22 0 -28 -6q-7 -3 -7 -20q0 -41 46 -58q50 -21 165 -21h28q16 0 23 -11q8 -8 11 -31q-17 -17 -55 -31q-36 -13 -53 -26q-40 -29 -64 -69q-23 -39 -23 -74q0 -21 10 -51q11 -33 11 -43v-6l-4 -15q-44 3 -64 41q-17 32 -19 82q-3 -1 -12 -1h-11q1 -5 1 -12 q0 -30 -23 -51t-54 -21q-47 0 -95 45q-48 46 -48 90q0 8 3 16q1 7 16 22q25 -31 34 -43q42 -59 76 -59q9 0 17 6q6 6 6 10q0 8 -12 29q-8 15 -37 53q-28 36 -45 50q-15 14 -22 14q-19 0 -37 -22t-18 -55zM145 282q0 -13 16 -45q14 -27 45 -68q31 -40 56 -62q24 -20 36 -20 q7 0 14 7q7 8 7 16q0 12 -18 58q-21 51 -46 92q-22 35 -39 49q-16 15 -31 15q-11 0 -25 -15q-15 -15 -15 -27zM190 714q0 -34 24 -107q22 -71 66 -190q10 6 28 6q1 0 6.5 -0.5t10.5 -0.5q4 0 26 -2l-69 200q-28 80 -44 104q-13 21 -26 21q-9 0 -15 -8q-7 -9 -7 -23zM356 204 q9 -23 19 -50q20 23 40 38q-5 1 -15 2.5t-15 2.5q-20 4 -29 7zM461 408l67 -12q45 124 69 199q25 81 25 96q0 16 -7 25q-4 7 -15 7q-14 0 -31 -27q-19 -29 -43 -101z" />
<glyph unicode="&#xdc;" d="M0 -100v800q0 41 29.5 70.5t70.5 29.5h800q41 0 70.5 -29.5t29.5 -70.5v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-800q-41 0 -70.5 29.5t-29.5 70.5zM200 300q0 -124 88 -212t212 -88t212 88t88 212t-88 212t-212 88t-212 -88t-88 -212zM300 300q0 82 59 141t141 59t141 -59 t59 -141t-59 -141t-141 -59t-141 59t-59 141z" />
<glyph unicode="&#xe0;" horiz-adv-x="617" d="M0 -43q0 76 57 112q29 19 54 29q114 49 122 54q-21 31 -54 68q-51 60 -60 71q-109 132 -94 247q7 55 42 91q13 14 42 32q37 21 45 25q5 2 22.5 9.5t29.5 12.5l47 21l69 30q58 25 86 40q20 11 25 -6q0 -11 -27 -25q-61 -40 -64 -114q-1 -29 5 -57.5t12.5 -47t25.5 -46 t27 -37.5t34.5 -40t31.5 -36q6 -7 29 -32.5t33 -37.5t28 -38t26 -46t15.5 -48.5t7.5 -58.5q0 -38 -13 -68q-12 -32 -28.5 -51.5t-47.5 -39.5q-35 -21 -53 -30q-23 -12 -61 -27q-16 -6 -35.5 -15t-22.5 -10l-89 -39l-36 -18q-32 -16 -50 -21q-85 -21 -133 24t-48 123z" />
<glyph unicode="&#xe1;" horiz-adv-x="1126" d="M0.5 367.5q9.5 158.5 74.5 265.5q49 80 95.5 113.5t138.5 49.5q30 5 57 5.5t50.5 -4t44 -11.5t39 -20t33.5 -25.5t30 -31.5t26.5 -34.5t24 -38.5t21 -39.5t20.5 -40.5q7 -14 14 -30t15 -35.5t13 -30.5q8 48 56.5 188t67.5 145q91 21 145 0q4 -2 9 -8t7 -8 q-1 -18 -6 -38.5t-8.5 -32.5t-13 -36.5t-11.5 -30.5l-160 -439q-7 -34 18.5 -90t67.5 -93t74 -22q10 5 18 21t14 21q18 15 71 15.5t67 -18.5q16 -29 11 -62.5t-31 -66t-59.5 -57t-74 -36.5t-73.5 -5q-29 6 -54 18.5t-41 25.5t-34 36.5t-27.5 38.5t-27 45t-25.5 44 q-4 -2 -6 -4q-24 -58 -81 -106.5t-127 -75t-150 -19.5t-145 54q-85 62 -131 203.5t-36.5 300zM153 380q-13 -108 9 -211t73 -141q28 -21 56 -30.5t51.5 -11.5t49 9.5t43 21t41 35t35.5 39.5t33 46t27.5 43t24.5 42q5 9 8 14q-38 161 -64 223q-73 173 -202 155 q-56 -8 -81 -22t-50 -49q-41 -55 -54 -163z" />
<glyph unicode="&#xe2;" horiz-adv-x="1078" d="M0 386.5q0 121.5 93 209.5q58 55 133.5 75t153 -1.5t137.5 -84.5q44 -46 62.5 -107t15 -115.5t-23.5 -102.5q-19 -41 -3 -93t40 -88.5t50.5 -68.5t26.5 -33l-11 9q-10 10 -21.5 20.5t-31 25.5t-38 27t-42.5 25t-45 18.5t-44.5 7.5t-42.5 -7q-47 -19 -103.5 -20t-117 22 t-102.5 69q-86 91 -86 212.5zM132 406q-9 -69 33.5 -124.5t111.5 -64.5t124 33.5t64 111.5t-33 124t-111 64t-124.5 -33t-64.5 -111zM610 700q21 59 74 87.5t113 8.5q58 -18 86.5 -72t8.5 -116q-24 -72 -114 -104q-31 -11 -55.5 -33.5t-34.5 -38t-23 -40.5q22 94 -24 159 q-55 80 -31 149zM648 205q2 92 63 155t152 63q89 0 152 -61.5t63 -156.5q0 -110 -110 -195q-38 -29 -62 -71t-30.5 -68t-12.5 -67q-4 40 -10 67t-30 69.5t-65 73.5q-111 83 -110 191zM686 677q-11 -27 0.5 -54.5t38.5 -38.5t54 0t38 38q11 28 0 55t-38 38t-54.5 0t-38.5 -38 zM752.5 162.5q18.5 -45.5 65.5 -65.5q46 -19 92 0.5t65 65.5t0 91.5t-65 65.5q-46 19 -92 0t-65 -65q-19 -47 -0.5 -92.5z" />
<glyph unicode="&#xe3;" horiz-adv-x="999" d="M0 -154q0 51 61 106.5t123 88.5l15 -22q-44 -32 -90.5 -82.5t-58.5 -89.5q87 27 265 379q65 131 103 261q-33 107 -33 202q0 115 47 115q23 0 34 -2t20.5 -13t9.5 -34q0 -15 -3 -28l-27 1q-2 26 -17 41q-12 -20 -12 -69q0 -38 9 -94q3 18 8.5 53.5t9.5 53.5l26 -3 q-2 -152 -14 -218q36 -107 86.5 -174t142.5 -119q68 7 116 7q178 0 178 -70q0 -11 -5 -24l-3 1q-5 -42 -67 -42q-104 0 -240 72q-220 -22 -389 -82q-147 -257 -235 -257q-7 0 -14 2t-12.5 4.5t-13.5 7t-12 6.5q-8 8 -8 22zM318 101q134 54 298 85q-103 73 -164 209 q-36 -121 -134 -294zM804 151q90 -35 142 -35q15 0 22 3q0 32 -145 32h-19z" />
<glyph unicode="&#xe4;" horiz-adv-x="875" d="M0 236q0 70 21 133t48.5 103t64.5 74.5t57 48t38 23.5q10 5 29.5 15t30.5 16t28.5 17t34.5 25q42 34 50 113q73 -88 106 -110q25 -17 73.5 -39t73.5 -37q19 -11 36 -23.5t54 -48.5t62.5 -76t46.5 -105t21 -137q0 -186 -127.5 -305t-306.5 -119q-116 0 -216.5 55.5 t-162.5 155.5t-62 221zM190 85q-2 -63 42 -93q31 -21 94 -21q41 0 97.5 29.5t105 58.5t70.5 28q23 -1 77.5 -56t70.5 -56q20 -1 33.5 8.5t31.5 35.5q33 49 33 117q0 29 -15 54.5t-47 25.5q-22 0 -92 -47t-94 -48q-22 0 -61 27.5t-88.5 55.5t-98.5 28q-65 -1 -111.5 -45 t-47.5 -102zM395 -95q-12 -10 0 -20q46 -42 165 -31q23 2 47.5 11.5t37 17.5t16.5 12t4 16q-3 12 -14 3q-41 -32 -124 -32q-75 0 -110 28q-3 2 -8 2t-14 -7zM485 -43q7 -8 28 11q2 1 8 6t8 6.5t8 5t10 4.5t11.5 2t15.5 1q16 0 26 -4.5t12.5 -8t7.5 -12.5q5 -10 7.5 -11.5 t7.5 0.5q12 7 7 20q-9 26 -22 34q-12 9 -43 9q-26 0 -41 -6q-17 -7 -44 -32q-15 -12 -7 -25z" />
<glyph unicode="&#xe5;" horiz-adv-x="979" d="M0 42q11 15 31.5 25.5t49 20t40.5 15.5q19 0 33.5 -4.5t33.5 -15t25 -12.5q47 -21 260 -119q19 -4 35.5 0t39.5 17.5t24 14.5q20 9 76.5 34.5t87.5 39.5q4 2 41.5 21t60.5 24q13 2 27.5 -1t23.5 -7.5t23 -13t18 -10.5t15.5 -6t18.5 -8t11 -11q3 -4 4 -14q-10 -13 -31 -24 t-51 -22t-40 -16q-43 -20 -128.5 -61.5t-128.5 -61.5q-7 -3 -21 -11.5t-23.5 -13t-25.5 -11t-27.5 -7t-29.5 1.5l-264 123q-6 3 -32 14t-51.5 22t-53.5 24t-46.5 23.5t-21.5 16.5q-4 4 -4 13zM0 310q11 15 31.5 25t50 20t41.5 15q19 0 34 -4.5t34.5 -15t25.5 -13.5 q42 -19 126.5 -58t127.5 -59q19 -5 37 -0.5t39 17t25 14.5q68 32 160 72q11 5 31.5 16.5t38.5 19.5t36 11q16 3 31.5 -1t37.5 -17t23 -13q5 -3 15.5 -6.5t18 -8t11.5 -10.5q3 -5 4 -14q-10 -14 -31.5 -25.5t-52.5 -22.5t-41 -16q-48 -23 -135.5 -65t-122.5 -59 q-7 -3 -26 -14t-29 -15t-32.5 -10t-35.5 0q-214 101 -260 122q-6 3 -44 19t-69.5 30t-61.5 29.5t-34 22.5q-4 4 -4 14zM0 577q10 15 31.5 26.5t52.5 22.5t41 16l348 162q30 0 53.5 -7t56.5 -26t40 -22q39 -18 117 -54.5t117 -54.5q4 -2 36.5 -15t54.5 -24t27 -20q3 -4 4 -13 q-9 -13 -26 -22.5t-43.5 -19t-34.5 -13.5q-47 -22 -140 -66.5t-139 -66.5q-6 -3 -20 -11t-23 -12.5t-25 -10.5t-27 -6t-28 1q-245 114 -256 119q-4 2 -63 27.5t-102 46.5t-48 30q-4 4 -4 13z" />
<glyph unicode="&#xe7;" horiz-adv-x="1137" d="M2.5 474q-7.5 215 11.5 270q4 9 9.5 15.5t14 12.5t13.5 9.5t17.5 10t16.5 8.5q136 0 386 2t329 2h40h54t55 -0.5t56.5 -2.5t45 -6t32.5 -10q16 -9 27 -24t16.5 -29.5t7.5 -40t2 -42t-0.5 -50t-0.5 -49.5q0 -207 -23 -327t-96 -213q-70 -88 -164.5 -139.5t-193 -62.5 t-200 11t-186.5 73.5t-151 133t-96 181.5q-15 52 -22.5 267zM234 476q-26 -28 15 -89.5t104 -123.5q2 -2 39.5 -40t53.5 -52t47 -35.5t57 -28.5q11 -3 22.5 -3t19.5 1t19.5 6.5t16 7.5t15.5 11.5t12 10.5t12 11l3 3q9 9 60.5 56t86 80.5t67.5 79t35 75.5q-15 40 -38 56 t-50.5 8.5t-56 -26t-59 -48t-56 -56t-49.5 -51t-37 -32.5q-27 16 -72.5 59.5t-82 82t-73.5 64t-55 14.5q-25 -15 -56 -41z" />
<glyph unicode="&#xe8;" d="M0 326q0 102 40 194q79 186 265 265q92 40 194 40t194 -40q184 -78 265 -265q40 -95 40 -194t-40 -194q-81 -188 -265 -267q-92 -40 -194 -40t-194 40q-186 80 -265 267q-40 92 -40 194zM78 326q0 -141 84 -252q83 -109 217 -155v80q0 60 40 87q-20 1 -47 7q-51 9 -87 32 q-91 55 -91 199q0 75 50 128q-23 59 5 128h20q10 0 25 -5q39 -12 87 -44q61 16 120 16t121 -16q39 26 73 40q32 12 46 10l12 -1q27 -69 5 -128q50 -53 50 -128q0 -112 -55 -169q-30 -32 -79 -50q-41 -15 -91 -19q41 -29 41 -87v-80q129 46 213 157q82 110 82 250 q0 85 -33 164q-32 76 -90 134q-56 56 -134 89q-80 34 -163 34q-82 0 -164 -34q-75 -32 -134 -89q-56 -58 -90 -134q-33 -79 -33 -164z" />
<glyph unicode="&#xe9;" horiz-adv-x="866" d="M0 660q0 60 127 102t306 42q180 0 306.5 -42t126.5 -102q0 -12 -72 -440q-9 -46 -111 -89t-250 -43t-250 43t-110 89q-73 414 -73 440zM107 79v4q0 17 15 17q6 0 12 -5q47 -37 122 -58t126 -23l51 -3q8 0 21.5 0.5t52.5 5t74.5 12.5t78.5 25t73 41l11 5q16 0 16 -17 q0 -2 -1 -4q-22 -121 -30 -161q-11 -49 -96 -81.5t-200 -32.5t-200 32.5t-95 81.5q-19 95 -31 161zM156 675q0 -24 81.5 -41.5t195.5 -17.5q115 0 196.5 17t81.5 41q0 25 -81.5 42.5t-196.5 17.5t-196 -17t-81 -42zM295 322q0 -57 40.5 -97.5t97.5 -40.5t97.5 40.5 t40.5 97.5t-40.5 97.5t-97.5 40.5t-97.5 -40.5t-40.5 -97.5zM364 322q0 -28 20 -48.5t49 -20.5t49 20.5t20 48.5t-20 48.5t-49 20.5t-49 -20.5t-20 -48.5z" />
<glyph unicode="&#xea;" horiz-adv-x="1272" d="M0 95h24q-7 14 -7 34q0 65 45.5 185.5t87.5 183.5q32 49 84 49q45 0 45 -34q0 -52 -72 -199h82q20 62 53 126q34 68 73 91t116 23q29 0 56.5 -14t27.5 -40t-13 -42t-37.5 -22.5t-43.5 -8.5t-46 -2h-9q-15 -22 -28 -58q18 3 37 3q64 0 64 -38q0 -9 -3 -18h19h-19 q-16 -59 -88 -59q-23 0 -50 5q-16 -48 -21 -73q52 10 77 10t43 -11.5t18 -35.5q0 -34 -23.5 -57t-53.5 -31t-64 -8q-65 0 -96 41h-19h19q-20 24 -20 62q0 23 3 45q8 50 28 112h-82q-9 -19 -26 -55.5t-25 -54.5h-1l-7 -14q22 2 34 2q59 0 59 -40q0 -51 -39 -73.5t-93 -22.5 q-65 0 -85 39h-24zM538 173q0 38 15.5 95t33.5 99q19 45 36 74t43 56.5t60.5 41t80.5 13.5q50 0 87 -19.5t37 -64.5q0 -38 -21 -68.5t-57 -30.5q-52 0 -52 33q0 6 3.5 17.5t3.5 18.5q0 13 -22 13q-17 0 -32.5 -14t-29 -43.5t-18 -40.5t-14.5 -39h16h-16q-32 -84 -32 -119 q0 -29 28 -29q25 0 44 24.5t26 52.5q-42 2 -42 35q0 37 28 54t66 17q52 0 65 -35h37h-37q4 -11 4 -26q0 -50 -28.5 -106t-68.5 -87h40h-40q-53 -41 -120 -41q-68 0 -100 41h-17h17q-24 29 -24 78zM867 95h42q-18 26 -18 66q0 79 49 204q19 47 32.5 74t37 55.5t57 41.5 t78.5 13q120 0 120 -115q0 -50 -22 -120h36h-36q-15 -51 -41 -110h38h-38q-37 -77 -73 -109h36h-36q-46 -41 -119 -41q-72 0 -101 41h-42zM1011 204h3q-6 -35 22 -35q23 0 43 38h-2q17 36 45 115.5t28 102.5q0 24 -21 24q-20 0 -33 -16q-18 -26 -52 -119h37h-37 q-25 -67 -33 -110z" />
<glyph unicode="&#xeb;" d="M0 304q0 136 67 251t182 182t251 67t251 -67t182 -182t67 -251t-67 -251t-182 -182t-251 -67t-251 67t-182 182t-67 251zM208 -15q0 -26 26 -26h176q28 0 28 26v48q0 26 -28 26h-29v460h29q28 0 28 26v48q0 26 -28 26h-176q-26 0 -26 -26v-48q0 -26 26 -26h31v-460h-31 q-26 0 -26 -26v-48zM485 -19q0 -24 24 -24h59q22 0 22 24v257q0 103 79 103q42 0 42 -51v-309q0 -24 22 -24h61q21 0 21 24v333q0 122 -110 122q-67 0 -122 -64l-7 36q-4 22 -24 22h-43q-24 0 -24 -25v-424z" />
<glyph unicode="&#xec;" horiz-adv-x="784" d="M0 -196v417l76 -1l-3 -335h501v334h79v-415h-653zM123 23h392v-83h-392v83zM124 88l8 85l393 -38l-8 -85zM145 261l23 82l380 -107l-24 -82zM216 462l44 73l338 -204l-45 -73zM383 667l69 50l230 -321l-70 -50zM635 790l84 14l65 -389l-84 -14z" />
<glyph unicode="&#xed;" horiz-adv-x="917" d="M0 804h161l197 -301q49 -75 102 -170q48 85 109 177l194 294h154l-399 -576v-424h-133v424z" />
<glyph unicode="&#xee;" horiz-adv-x="1200" d="M0 289v34q0 113 84 197t215 84q136 0 247 -112q21 -20 54 -62l96 -126q39 -52 52 -65q74 -74 147 -74q59 0 96 40q33 33 38 85q1 5 1 14q0 22 -6 41q-9 31 -33 57q0 1 -1 1q-38 40 -95 40q-78 0 -147 -74l-85 111h1h-1q-6 8 -10 13q55 60 113 85.5t134 25.5 q124 0 214 -84h1l1 -1q83 -83 83 -215q0 -30 -5 -63q-16 -89 -79 -153q-61 -62 -150 -79q-33 -5 -62 -5q-140 0 -248 109q-23 23 -56 67l-96 124q-39 52 -52 65q-74 74 -149 74q-22 0 -40 -6q-29 -8 -55 -34q-29 -32 -36 -71q-3 -14 -3 -28q0 -57 37 -97l2 -2q39 -40 97 -40 q79 0 147 75l84 -110l9 -12q-57 -61 -115 -87t-130 -26q-131 0 -216 83v1q-63 63 -78 153q-5 25 -5 47z" />
<glyph unicode="&#x2000;" horiz-adv-x="482" />
<glyph unicode="&#x2001;" horiz-adv-x="964" />
<glyph unicode="&#x2002;" horiz-adv-x="482" />
<glyph unicode="&#x2003;" horiz-adv-x="964" />
<glyph unicode="&#x2004;" horiz-adv-x="321" />
<glyph unicode="&#x2005;" horiz-adv-x="241" />
<glyph unicode="&#x2006;" horiz-adv-x="160" />
<glyph unicode="&#x2007;" horiz-adv-x="160" />
<glyph unicode="&#x2008;" horiz-adv-x="120" />
<glyph unicode="&#x2009;" horiz-adv-x="192" />
<glyph unicode="&#x200a;" horiz-adv-x="53" />
<glyph unicode="&#x2010;" horiz-adv-x="939" d="M-0.5 707q-0.5 11 6 20.5t13.5 16.5t23.5 15.5t27 13t33 14t34.5 14.5q54 22 97 16t54 -35q25 -67 102.5 -319.5t115.5 -361.5q268 88 326 105q16 6 37.5 4t32.5 -23q23 -47 32.5 -98.5t0.5 -74.5q-19 -15 -59.5 -32t-75.5 -29t-89.5 -29t-73.5 -23q-10 -3 -38 -13 t-53 -18.5t-58 -19t-61 -17.5t-54 -11.5t-44.5 -3.5t-25.5 9q-18 18 -32 52t-29 87t-19 66q-42 125 -113 338.5t-104 312.5q-6 13 -6.5 24z" />
<glyph unicode="&#x2011;" horiz-adv-x="939" d="M-0.5 707q-0.5 11 6 20.5t13.5 16.5t23.5 15.5t27 13t33 14t34.5 14.5q54 22 97 16t54 -35q25 -67 102.5 -319.5t115.5 -361.5q268 88 326 105q16 6 37.5 4t32.5 -23q23 -47 32.5 -98.5t0.5 -74.5q-19 -15 -59.5 -32t-75.5 -29t-89.5 -29t-73.5 -23q-10 -3 -38 -13 t-53 -18.5t-58 -19t-61 -17.5t-54 -11.5t-44.5 -3.5t-25.5 9q-18 18 -32 52t-29 87t-19 66q-42 125 -113 338.5t-104 312.5q-6 13 -6.5 24z" />
<glyph unicode="&#x2012;" horiz-adv-x="939" d="M-0.5 707q-0.5 11 6 20.5t13.5 16.5t23.5 15.5t27 13t33 14t34.5 14.5q54 22 97 16t54 -35q25 -67 102.5 -319.5t115.5 -361.5q268 88 326 105q16 6 37.5 4t32.5 -23q23 -47 32.5 -98.5t0.5 -74.5q-19 -15 -59.5 -32t-75.5 -29t-89.5 -29t-73.5 -23q-10 -3 -38 -13 t-53 -18.5t-58 -19t-61 -17.5t-54 -11.5t-44.5 -3.5t-25.5 9q-18 18 -32 52t-29 87t-19 66q-42 125 -113 338.5t-104 312.5q-6 13 -6.5 24z" />
<glyph unicode="&#x2013;" horiz-adv-x="499" d="M0 707q0 11 3.5 20.5t7 16.5t12.5 15.5t14.5 13t17.5 14t18 14.5q29 22 52 16t28 -35q14 -67 55 -319.5t61 -361.5q143 88 174 105q8 6 19.5 4t17.5 -23q12 -47 17 -98.5t1 -74.5q-10 -15 -32 -32t-40.5 -29t-47.5 -29t-39 -23q-5 -3 -20 -13t-28.5 -18.5t-31 -19 t-32 -17.5t-28.5 -11.5t-24 -3.5t-14 9q-9 18 -16.5 52t-15.5 87t-10 66q-22 125 -60 338.5t-56 312.5q-3 13 -3 24z" />
<glyph unicode="&#x2014;" d="M0.5 707q-0.5 11 6 20.5t14 16.5t25 15.5t29 13t35.5 14t36 14.5q58 22 103.5 16t57.5 -35q27 -67 109 -319.5t123 -361.5q285 88 347 105q17 6 40 4t34 -23q25 -47 35 -98.5t0 -74.5q-20 -15 -63 -32t-80.5 -29t-95 -29t-78.5 -23q-10 -3 -40 -13t-56.5 -18.5t-61.5 -19 t-65 -17.5t-57.5 -11.5t-47.5 -3.5t-27 9q-19 18 -34 52t-31 87t-20 66q-45 125 -120.5 338.5t-110.5 312.5q-6 13 -6.5 24z" />
<glyph unicode="&#x202f;" horiz-adv-x="192" />
<glyph unicode="&#x205f;" horiz-adv-x="241" />
<glyph unicode="&#xe000;" horiz-adv-x="820" d="M0 0v820h820v-820h-820z" />
<glyph horiz-adv-x="664" />
</font>
</defs></svg>

After

Width:  |  Height:  |  Size: 77 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

View file

@ -0,0 +1,75 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Log in to Subway</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" type="text/css" href="css/base.css">
<link rel="stylesheet" type="text/css" href="css/forms.css">
<link rel="stylesheet" type="text/css" href="css/zocial/zocial.css">
<link rel="stylesheet" type="text/css" href="css/login-screen.css">
<link rel="stylesheet" type="text/css" href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic'>
</head>
<body class="rcue-login-register customer">
<h1><a href="#" title="Go to the home page"><img src="img/subway-logo.png" alt="Subway logo"></a></h1>
<div class="content">
<h2>Log in to <strong>Subway</strong></h2>
<p class="powered"><a href="#">Powered by Keycloak</a></p>
<div class="background-area">
<div class="form-area social clearfix">
<section class="app-form">
<h3>Application login area</h3>
<form>
<div>
<label for="username">Username</label><input type="text" id="username" autofocus>
</div>
<div>
<label for="password">Password</label><input type="password" id="password">
</div>
<div>
<label for="one-time-pswd" class="two-lines">One-time-password</label><input type="password" id="one-time-pswd">
</div>
<div class="aside-btn">
<input type="checkbox" id="remember"><label for="remember">Remember Username</label>
<p>Forgot <a href="#">Username</a> or <a href="#">Password</a>?</p>
</div>
<input type="button" value="Log In">
</form>
</section>
<section class="social-login">
<span>or</span>
<h3>Social login area</h3>
<p>Log In with</p>
<ul>
<li>
<a href="#" class="zocial facebook">
<span class="text">Facebook</span>
</a>
</li>
<li>
<a href="#" class="zocial googleplus">
<span class="text">Google</span>
</a>
</li>
<li>
<a href="#" class="zocial twitter">
<span class="text">Twitter</span>
</a>
</li>
</ul>
</section>
<section class="info-area">
<h3>Info area</h3>
<p>Does not have an account? <a href="realm-register.html">Register</a>.</p>
<ul>
<li><strong>Domain:</strong> 10.0.0.1</li>
<li><strong>Zone:</strong> Live</li>
<li><strong>Appliance:</strong> Yep</li>
</ul>
</section>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,81 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Register with Subway</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" type="text/css" href="css/base.css">
<link rel="stylesheet" type="text/css" href="css/forms.css">
<link rel="stylesheet" type="text/css" href="css/zocial/zocial.css">
<link rel="stylesheet" type="text/css" href="css/login-screen.css">
<link rel="stylesheet" type="text/css" href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic'>
</head>
<body class="rcue-login-register customer register">
<h1><a href="#" title="Go to the home page"><img src="img/subway-logo.png" alt="Subway logo"></a></h1>
<div class="content">
<h2>Log in to <strong>Subway</strong></h2>
<p class="powered"><a href="#">Powered by Keycloak</a></p>
<div class="background-area">
<div class="form-area social clearfix">
<section class="app-form">
<h3>Application login area</h3>
<form>
<p class="subtitle">All fields required</p>
<div>
<label for="name">Full name</label><input type="text" id="name" autofocus>
</div>
<div>
<label for="email">Email</label><input type="email" id="email">
</div>
<div>
<label for="username">Username</label><input type="text" id="username">
</div>
<div>
<label for="password">Password</label><input type="password" id="password" placeholder="At least 6 characters">
</div>
<div>
<label for="password-confirm" class="two-lines">Password confirmation</label><input type="password" id="password-confirm">
</div>
<div class="aside-btn">
<p>By registering you agree to the <a href="#">Terms of Service</a> and the <a href="#">Privacy Policy</a>.</p>
</div>
<input type="button" value="Register">
</form>
</section>
<section class="social-login">
<span>or</span>
<h3>Social login area</h3>
<p>Log In with</p>
<ul>
<li>
<a href="#" class="zocial facebook">
<span class="text">Facebook</span>
</a>
</li>
<li>
<a href="#" class="zocial googleplus">
<span class="text">Google</span>
</a>
</li>
<li>
<a href="#" class="zocial twitter">
<span class="text">Twitter</span>
</a>
</li>
</ul>
</section>
<section class="info-area">
<h3>Info area</h3>
<p>Already have an account? <a href="realm-login.html">Log in</a>.</p>
<ul>
<li><strong>Domain:</strong> 10.0.0.1</li>
<li><strong>Zone:</strong> Live</li>
<li><strong>Appliance:</strong> Yep</li>
</ul>
</section>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,77 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Log in to Keycloak</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" type="text/css" href="css/base.css">
<link rel="stylesheet" type="text/css" href="css/forms.css">
<link rel="stylesheet" type="text/css" href="css/zocial/zocial.css">
<link rel="stylesheet" type="text/css" href="css/login-screen.css">
<link rel="stylesheet" type="text/css" href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic'>
</head>
<body class="rcue-login-register">
<h1><a href="#" title="Go to the home page"><img src="img/red-hat-logo.png" alt="Red Hat logo"></a></h1>
<div class="content">
<h2>Log in to <strong>Keycloak</strong></h2>
<div class="background-area">
<div class="form-area social clearfix">
<section class="app-form">
<h3>Application login area</h3>
<form action="rest/saas/login" method="POST">
<div class="feedback feedback-error">
<p><font color="red"><strong>Email is not valid</strong>. Please enter a valid email address.</font></p>
</div>
<div>
<label for="username">Username</label><input type="text" id="username" autofocus>
</div>
<div>
<label for="password">Password</label><input type="password" id="password">
</div> <!--
<div>
<label for="one-time-pswd" class="two-lines">One-time-password</label><input type="password" id="one-time-pswd">
</div> -->
<div class="aside-btn">
<input type="checkbox" id="remember"><label for="remember">Remember Username</label>
<p>Forgot <a href="#">Username</a> or <a href="#">Password</a>?</p>
</div>
<input type="button" value="Log In">
</form>
</section>
<section class="social-login">
<span>or</span>
<h3>Social login area</h3>
<p>Log In with</p>
<ul>
<li>
<a href="#" class="zocial facebook">
<span class="text">Facebook</span>
</a>
</li>
<li>
<a href="#" class="zocial googleplus">
<span class="text">Google</span>
</a>
</li>
<li>
<a href="#" class="zocial twitter">
<span class="text">Twitter</span>
</a>
</li>
</ul>
</section>
<section class="info-area">
<h3>Info area</h3>
<p>Does not have an account? <a href="saas-register.html">Register</a>.</p>
<ul>
<li><strong>Domain:</strong> 10.0.0.1</li>
<li><strong>Zone:</strong> Live</li>
<li><strong>Appliance:</strong> Yep</li>
</ul>
</section>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,82 @@
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%><!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Log in to Keycloak</title>
<link rel="stylesheet" href="<%=application.getContextPath()%>/saas/css/reset.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/base.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/forms.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/zocial/zocial.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/login-screen.css">
<link rel="stylesheet" type="text/css" href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic'>
</head>
<body class="rcue-login-register">
<h1><a href="#" title="Go to the home page"><img src="<%=application.getContextPath()%>/saas/img/red-hat-logo.png" alt="Red Hat logo"></a></h1>
<div class="content">
<h2>Log in to <strong>Keycloak</strong></h2>
<div class="background-area">
<div class="form-area social clearfix">
<section class="app-form">
<h3>Application login area</h3>
<form action="<%=application.getContextPath()%>/rest/saas/login" method="POST">
<%
String errorMessage = (String)request.getAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE");
if (errorMessage != null) { %>
<div class="feedback feedback-error">
<p><font color="red"><%=errorMessage%></font></p>
</div>
<% } %>
<div>
<label for="username">Username</label><input type="text" id="username" name="username" autofocus>
</div>
<div>
<label for="password">Password</label><input type="password" name="Password" id="password">
</div> <!--
<div>
<label for="one-time-pswd" class="two-lines">One-time-password</label><input type="password" id="one-time-pswd">
</div> -->
<div class="aside-btn">
<input type="checkbox" id="remember"><label for="remember">Remember Username</label>
<p>Forgot <a href="#">Username</a> or <a href="#">Password</a>?</p>
</div>
<input type="submit" value="Log In">
</form>
</section>
<section class="social-login">
<span>or</span>
<h3>Social login area</h3>
<p>Log In with</p>
<ul>
<li>
<a href="#" class="zocial facebook">
<span class="text">Facebook</span>
</a>
</li>
<li>
<a href="#" class="zocial googleplus">
<span class="text">Google</span>
</a>
</li>
<li>
<a href="#" class="zocial twitter">
<span class="text">Twitter</span>
</a>
</li>
</ul>
</section>
<section class="info-area">
<h3>Info area</h3>
<p>Does not have an account? <a href="saas-register.html">Register</a>.</p>
<ul>
<li><strong>Domain:</strong> 10.0.0.1</li>
<li><strong>Zone:</strong> Live</li>
<li><strong>Appliance:</strong> Yep</li>
</ul>
</section>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,80 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Register with Keycloak</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" type="text/css" href="css/base.css">
<link rel="stylesheet" type="text/css" href="css/forms.css">
<link rel="stylesheet" type="text/css" href="css/zocial/zocial.css">
<link rel="stylesheet" type="text/css" href="css/login-screen.css">
<link rel="stylesheet" type="text/css" href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic'>
</head>
<body class="rcue-login-register register">
<h1><a href="#" title="Go to the home page"><img src="img/red-hat-logo.png" alt="Red Hat logo"></a></h1>
<div class="content">
<h2>Register with <strong>Keycloak</strong></h2>
<div class="background-area">
<div class="form-area social clearfix">
<section class="app-form">
<h3>Application login area</h3>
<form>
<p class="subtitle">All fields required</p>
<div>
<label for="name">Full name</label><input type="text" id="name" autofocus>
</div>
<div>
<label for="email">Email</label><input type="email" id="email">
</div>
<div>
<label for="username">Username</label><input type="text" id="username">
</div>
<div>
<label for="password">Password</label><input type="password" id="password" placeholder="At least 6 characters">
</div>
<div>
<label for="password-confirm" class="two-lines">Password confirmation</label><input type="password" id="password-confirm">
</div>
<div class="aside-btn">
<p>By registering you agree to the <a href="#">Terms of Service</a> and the <a href="#">Privacy Policy</a>.</p>
</div>
<input type="button" value="Register">
</form>
</section>
<section class="social-login">
<span>or</span>
<h3>Social login area</h3>
<p>Log In with</p>
<ul>
<li>
<a href="#" class="zocial facebook">
<span class="text">Facebook</span>
</a>
</li>
<li>
<a href="#" class="zocial googleplus">
<span class="text">Google</span>
</a>
</li>
<li>
<a href="#" class="zocial twitter">
<span class="text">Twitter</span>
</a>
</li>
</ul>
</section>
<section class="info-area">
<h3>Info area</h3>
<p>Already have an account? <a href="saas-login.html">Log in</a>.</p>
<ul>
<li><strong>Domain:</strong> 10.0.0.1</li>
<li><strong>Zone:</strong> Live</li>
<li><strong>Appliance:</strong> Yep</li>
</ul>
</section>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,88 @@
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%><!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Register with Keycloak</title>
<link rel="stylesheet" href="<%=application.getContextPath()%>/saas/css/reset.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/base.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/forms.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/zocial/zocial.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/login-screen.css">
<link rel="stylesheet" type="text/css" href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic'>
</head>
<body class="rcue-login-register register">
<h1><a href="#" title="Go to the home page"><img src="<%=application.getContextPath()%>/saas/img/red-hat-logo.png" alt="Red Hat logo"></a></h1>
<div class="content">
<h2>Register with <strong>Keycloak</strong></h2>
<div class="background-area">
<div class="form-area social clearfix">
<section class="app-form">
<h3>Application login area</h3>
<form action="<%=application.getContextPath()%>/rest/saas/registrations" method="POST">
<%
String errorMessage = (String)request.getAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE");
if (errorMessage != null) { %>
<div class="feedback feedback-error">
<p><font color="red"><%=errorMessage%></font></p>
</div>
<% } %>
<p class="subtitle">All fields required</p>
<div>
<label for="name">Full name</label><input type="text" id="name" name="name" autofocus>
</div>
<div>
<label for="email">Email</label><input type="email" id="email" name="email">
</div>
<div>
<label for="username">Username</label><input type="text" id="username" name="username">
</div>
<div>
<label for="password">Password</label><input type="password" id="password" placeholder="At least 6 characters" name="password">
</div>
<div>
<label for="password-confirm" class="two-lines">Password confirmation</label><input type="password" id="password-confirm" name="password-confirm">
</div>
<div class="aside-btn">
<p>By registering you agree to the <a href="#">Terms of Service</a> and the <a href="#">Privacy Policy</a>.</p>
</div>
<input type="submit" value="Register">
</form>
</section>
<section class="social-login">
<span>or</span>
<h3>Social login area</h3>
<p>Log In with</p>
<ul>
<li>
<a href="#" class="zocial facebook">
<span class="text">Facebook</span>
</a>
</li>
<li>
<a href="#" class="zocial googleplus">
<span class="text">Google</span>
</a>
</li>
<li>
<a href="#" class="zocial twitter">
<span class="text">Twitter</span>
</a>
</li>
</ul>
</section>
<section class="info-area">
<h3>Info area</h3>
<p>Already have an account? <a href="saas-login.html">Log in</a>.</p>
<ul>
<li><strong>Domain:</strong> 10.0.0.1</li>
<li><strong>Zone:</strong> Live</li>
<li><strong>Appliance:</strong> Yep</li>
</ul>
</section>
</div>
</div>
</div>
</body>
</html>

View file

@ -3,25 +3,22 @@ package org.keycloak.services.filters;
import org.jboss.resteasy.logging.Logger;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.services.models.KeycloakSession;
import org.keycloak.services.models.KeycloakSessionFactory;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.PreMatching;
import java.io.IOException;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class KeycloakSessionResponseFilter implements ContainerResponseFilter {
protected static final Logger logger = Logger.getLogger(KeycloakSessionResponseFilter.class);
public class KeycloakSessionCleanupFilter implements ContainerResponseFilter {
protected static final Logger logger = Logger.getLogger(KeycloakSessionCleanupFilter.class);
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
KeycloakSession ctx = (KeycloakSession)requestContext.getProperty(KeycloakSession.class.getName());
KeycloakSession ctx = ResteasyProviderFactory.getContextData(KeycloakSession.class);
if (ctx != null) ctx.close();
}
}

Some files were not shown because too many files have changed in this diff Show more