tags)
-@link-color: @light-blue;
-@link-hover-color: lighten(@link-color, 15%);
-
-// Body background (Affects main content background only)
-@body-bg: #ecf0f5; // DEPRECATED
-@content-bg: #ecf0f5;
-
-// SIDEBAR SKINS
-// --------------------------------------------------------
-
-// Dark sidebar
-@sidebar-dark-bg: #222d32;
-@sidebar-dark-hover-bg: darken(@sidebar-dark-bg, 2%);
-@sidebar-dark-color: lighten(@sidebar-dark-bg, 60%);
-@sidebar-dark-hover-color: #fff;
-@sidebar-dark-submenu-bg: lighten(@sidebar-dark-bg, 5%);
-@sidebar-dark-submenu-color: lighten(@sidebar-dark-submenu-bg, 40%);
-@sidebar-dark-submenu-hover-color: #fff;
-
-// Light sidebar
-@sidebar-light-bg: #f9fafc;
-@sidebar-light-hover-bg: lighten(#f0f0f1, 1.5%);
-@sidebar-light-color: #444;
-@sidebar-light-hover-color: #000;
-@sidebar-light-submenu-bg: @sidebar-light-hover-bg;
-@sidebar-light-submenu-color: #777;
-@sidebar-light-submenu-hover-color: #000;
-
-// sidebar-expanded-on-hover
-@sidebar-expanded-shadow: 3px 0 8px rgba(0,0,0,.125);
-
-// CONTROL SIDEBAR
-// --------------------------------------------------------
-@control-sidebar-width: @sidebar-width;
-
-// BOXES
-// --------------------------------------------------------
-@box-border-color: #f4f4f4;
-@box-border-radius: 3px;
-@box-footer-bg: #fff;
-@box-boxshadow: 0 1px 1px rgba(0, 0, 0, .1);
-@box-padding: 10px;
-
-// Box variants
-@box-default-border-top-color: #d2d6de;
-
-// BUTTONS
-// --------------------------------------------------------
-@btn-boxshadow: none;
-
-// PROGRESS BARS
-// --------------------------------------------------------
-@progress-bar-border-radius: 1px;
-@progress-bar-sm-border-radius: 1px;
-@progress-bar-xs-border-radius: 1px;
-
-// FORMS
-// --------------------------------------------------------
-@input-radius: 0;
-
-// BUTTONS
-// --------------------------------------------------------
-
-// Border radius for non flat buttons
-@btn-border-radius: 3px;
-
-// DIRECT CHAT
-// --------------------------------------------------------
-@direct-chat-height: 250px;
-@direct-chat-default-msg-bg: @gray-lte;
-@direct-chat-default-font-color: #444;
-@direct-chat-default-msg-border-color: @gray-lte;
-
-// CHAT WIDGET
-// --------------------------------------------------------
-@attachment-border-radius: 3px;
-
-// TRANSITIONS SETTINGS
-// --------------------------------------------------------
-
-// Transition global options
-@transition-speed: .3s;
-@transition-fn: ease-in-out;
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/adminlte-options.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/adminlte-options.html
deleted file mode 100644
index 098aab3..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/adminlte-options.html
+++ /dev/null
@@ -1,125 +0,0 @@
-
-
- Modifying the options of AdminLTE's app.js can be done using one of the following ways.
-
- Editing app.js
- Within the main Javascript file, modify the $.AdminLTE.options
object to suit your use case.
-
- Defining AdminLTEOptions
- Alternatively, you can define a global options variable named AdminLTEOptions
and initialize it before loading app.js.
- Example
- <script>
- var AdminLTEOptions = {
- //Enable sidebar expand on hover effect for sidebar mini
- //This option is forced to true if both the fixed layout and sidebar mini
- //are used together
- sidebarExpandOnHover: true,
- //BoxRefresh Plugin
- enableBoxRefresh: true,
- //Bootstrap.js tooltip
- enableBSToppltip: true
- };
-</script>
-<script src="dist/js/app.js" type="text/javascript"></script>
-
- Available AdminLTE Options
- {
- //Add slimscroll to navbar menus
- //This requires you to load the slimscroll plugin
- //in every page before app.js
- navbarMenuSlimscroll: true,
- navbarMenuSlimscrollWidth: "3px", //The width of the scroll bar
- navbarMenuHeight: "200px", //The height of the inner menu
- //General animation speed for JS animated elements such as box collapse/expand and
- //sidebar treeview slide up/down. This option accepts an integer as milliseconds,
- //'fast', 'normal', or 'slow'
- animationSpeed: 500,
- //Sidebar push menu toggle button selector
- sidebarToggleSelector: "[data-toggle='offcanvas']",
- //Activate sidebar push menu
- sidebarPushMenu: true,
- //Activate sidebar slimscroll if the fixed layout is set (requires SlimScroll Plugin)
- sidebarSlimScroll: true,
- //Enable sidebar expand on hover effect for sidebar mini
- //This option is forced to true if both the fixed layout and sidebar mini
- //are used together
- sidebarExpandOnHover: false,
- //BoxRefresh Plugin
- enableBoxRefresh: true,
- //Bootstrap.js tooltip
- enableBSToppltip: true,
- BSTooltipSelector: "[data-toggle='tooltip']",
- //Enable Fast Click. Fastclick.js creates a more
- //native touch experience with touch devices. If you
- //choose to enable the plugin, make sure you load the script
- //before AdminLTE's app.js
- enableFastclick: true,
- //Control Sidebar Tree Views
- enableControlTreeView: true,
- //Control Sidebar Options
- enableControlSidebar: true,
- controlSidebarOptions: {
- //Which button should trigger the open/close event
- toggleBtnSelector: "[data-toggle='control-sidebar']",
- //The sidebar selector
- selector: ".control-sidebar",
- //Enable slide over content
- slide: true
- },
- //Box Widget Plugin. Enable this plugin
- //to allow boxes to be collapsed and/or removed
- enableBoxWidget: true,
- //Box Widget plugin options
- boxWidgetOptions: {
- boxWidgetIcons: {
- //Collapse icon
- collapse: 'fa-minus',
- //Open icon
- open: 'fa-plus',
- //Remove icon
- remove: 'fa-times'
- },
- boxWidgetSelectors: {
- //Remove button selector
- remove: '[data-widget="remove"]',
- //Collapse button selector
- collapse: '[data-widget="collapse"]'
- }
- },
- //Direct Chat plugin options
- directChat: {
- //Enable direct chat by default
- enable: true,
- //The button to open and close the chat contacts pane
- contactToggleSelector: '[data-widget="chat-pane-toggle"]'
- },
- //Define the set of colors to use globally around the website
- colors: {
- lightBlue: "#3c8dbc",
- red: "#f56954",
- green: "#00a65a",
- aqua: "#00c0ef",
- yellow: "#f39c12",
- blue: "#0073b7",
- navy: "#001F3F",
- teal: "#39CCCC",
- olive: "#3D9970",
- lime: "#01FF70",
- orange: "#FF851B",
- fuchsia: "#F012BE",
- purple: "#8E24AA",
- maroon: "#D81B60",
- black: "#222222",
- gray: "#d2d6de"
- },
- //The standard screen sizes that bootstrap uses.
- //If you change these in the variables.less file, change
- //them here too.
- screenSizes: {
- xs: 480,
- sm: 768,
- md: 992,
- lg: 1200
- }
-}
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/advice.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/advice.html
deleted file mode 100644
index 6c0d49e..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/advice.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Before you go to see your new awesome theme, here are few tips on how to familiarize yourself with it:
-
-
-
- - AdminLTE is based on Bootstrap 3. If you are unfamiliar with Bootstrap, visit their website and read through the documentation. All of Bootstrap components have been modified to fit the style of AdminLTE and provide a consistent look throughout the template. This way, we guarantee you will get the best of AdminLTE.
- - Go through the pages that are bundled with the theme. Most of the template example pages contain quick tips on how to create or use a component which can be really helpful when you need to create something on the fly.
- - Documentation. We are trying our best to make your experience with AdminLTE be smooth. One way to achieve that is to provide documentation and support. If you think that something is missing from the documentation, please do not hesitate to create an issue to tell us about it.
- - Built with LESS. This theme uses the LESS compiler to make it easier to customize and use. LESS is easy to learn if you know CSS or SASS. It is not necessary to learn LESS but it will benefit you a lot in the future.
- - Hosted on GitHub. Visit our GitHub repository to view issues, make requests, or contribute to the project.
-
-
- Note: LESS files are better commented than the compiled CSS file.
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/browsers.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/browsers.html
deleted file mode 100644
index cb84121..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/browsers.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- AdminLTE supports the following browsers:
-
- - IE9+
- - Firefox (latest)
- - Safari (latest)
- - Chrome (latest)
- - Opera (latest)
-
- Note: IE9 does not support transitions or animations. The template will function properly but it won't use animations/transitions on IE9.
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/components.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/components.html
deleted file mode 100644
index a2d9009..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/components.html
+++ /dev/null
@@ -1,1545 +0,0 @@
-
-
-
-
Reminder!
-
- AdminLTE uses all of Bootstrap 3 components. It's a good start to review
- the Bootstrap documentation to get an idea of the various components
- that this documentation does not cover.
-
-
-
-
Tip!
-
- If you go through the example pages and would like to copy a component, right-click on
- the component and choose "inspect element" to get to the HTML quicker than scanning
- the HTML page.
-
-
- Main Header
- The main header contains the logo and navbar. Construction of the
- navbar differs slightly from Bootstrap because it has components that Bootstrap doesn't provide.
- The navbar can be constructed in two ways. This is an example for the normal navbar and next we will provide an example for
- the top nav layout.
-
-
-
Main Header Example
-
-
- AdminLTE
-
-
-
-
-
- <header class="main-header">
- <a href="../../index2.html" class="logo">
- <!-- LOGO -->
- AdminLTE
- </a>
- <!-- Header Navbar: style can be found in header.less -->
- <nav class="navbar navbar-static-top" role="navigation">
- <!-- Navbar Right Menu -->
- <div class="navbar-custom-menu">
- <ul class="nav navbar-nav">
- <!-- Messages: style can be found in dropdown.less-->
- <li class="dropdown messages-menu">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">
- <i class="fa fa-envelope-o"></i>
- <span class="label label-success">4</span>
- </a>
- <ul class="dropdown-menu">
- <li class="header">You have 4 messages</li>
- <li>
- <!-- inner menu: contains the actual data -->
- <ul class="menu">
- <li><!-- start message -->
- <a href="#">
- <div class="pull-left">
- <img src="dist/img/user2-160x160.jpg" class="img-circle" alt="User Image">
- </div>
- <h4>
- Sender Name
- <small><i class="fa fa-clock-o"></i> 5 mins</small>
- </h4>
- <p>Message Excerpt</p>
- </a>
- </li><!-- end message -->
- ...
- </ul>
- </li>
- <li class="footer"><a href="#">See All Messages</a></li>
- </ul>
- </li>
- <!-- Notifications: style can be found in dropdown.less -->
- <li class="dropdown notifications-menu">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">
- <i class="fa fa-bell-o"></i>
- <span class="label label-warning">10</span>
- </a>
- <ul class="dropdown-menu">
- <li class="header">You have 10 notifications</li>
- <li>
- <!-- inner menu: contains the actual data -->
- <ul class="menu">
- <li>
- <a href="#">
- <i class="ion ion-ios-people info"></i> Notification title
- </a>
- </li>
- ...
- </ul>
- </li>
- <li class="footer"><a href="#">View all</a></li>
- </ul>
- </li>
- <!-- Tasks: style can be found in dropdown.less -->
- <li class="dropdown tasks-menu">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">
- <i class="fa fa-flag-o"></i>
- <span class="label label-danger">9</span>
- </a>
- <ul class="dropdown-menu">
- <li class="header">You have 9 tasks</li>
- <li>
- <!-- inner menu: contains the actual data -->
- <ul class="menu">
- <li><!-- Task item -->
- <a href="#">
- <h3>
- Design some buttons
- <small class="pull-right">20%</small>
- </h3>
- <div class="progress xs">
- <div class="progress-bar progress-bar-aqua" style="width: 20%" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100">
- <span class="sr-only">20% Complete</span>
- </div>
- </div>
- </a>
- </li><!-- end task item -->
- ...
- </ul>
- </li>
- <li class="footer">
- <a href="#">View all tasks</a>
- </li>
- </ul>
- </li>
- <!-- User Account: style can be found in dropdown.less -->
- <li class="dropdown user user-menu">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">
- <img src="dist/img/user2-160x160.jpg" class="user-image" alt="User Image">
- <span class="hidden-xs">Alexander Pierce</span>
- </a>
- <ul class="dropdown-menu">
- <!-- User image -->
- <li class="user-header">
- <img src="dist/img/user2-160x160.jpg" class="img-circle" alt="User Image">
- <p>
- Alexander Pierce - Web Developer
- <small>Member since Nov. 2012</small>
- </p>
- </li>
- <!-- Menu Body -->
- <li class="user-body">
- <div class="col-xs-4 text-center">
- <a href="#">Followers</a>
- </div>
- <div class="col-xs-4 text-center">
- <a href="#">Sales</a>
- </div>
- <div class="col-xs-4 text-center">
- <a href="#">Friends</a>
- </div>
- </li>
- <!-- Menu Footer-->
- <li class="user-footer">
- <div class="pull-left">
- <a href="#" class="btn btn-default btn-flat">Profile</a>
- </div>
- <div class="pull-right">
- <a href="#" class="btn btn-default btn-flat">Sign out</a>
- </div>
- </li>
- </ul>
- </li>
- </ul>
- </div>
- </nav>
-</header>
- Top Nav Layout. Main Header Example.
-
-
Reminder!
-
To use this main header instead of the regular one, you must add the layout-top-nav
class to the body tag.
-
-
-
-<header class="main-header">
- <nav class="navbar navbar-static-top">
- <div class="container-fluid">
- <div class="navbar-header">
- <a href="../../index2.html" class="navbar-brand"><b>Admin</b>LTE</a>
- <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse">
- <i class="fa fa-bars"></i>
- </button>
- </div>
-
- <!-- Collect the nav links, forms, and other content for toggling -->
- <div class="collapse navbar-collapse" id="navbar-collapse">
- <ul class="nav navbar-nav">
- <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
- <li><a href="#">Link</a></li>
- <li class="dropdown">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
- <ul class="dropdown-menu" role="menu">
- <li><a href="#">Action</a></li>
- <li><a href="#">Another action</a></li>
- <li><a href="#">Something else here</a></li>
- <li class="divider"></li>
- <li><a href="#">Separated link</a></li>
- <li class="divider"></li>
- <li><a href="#">One more separated link</a></li>
- </ul>
- </li>
- </ul>
- <form class="navbar-form navbar-left" role="search">
- <div class="form-group">
- <input type="text" class="form-control" id="navbar-search-input" placeholder="Search">
- </div>
- </form>
- <ul class="nav navbar-nav navbar-right">
- <li><a href="#">Link</a></li>
- <li class="dropdown">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
- <ul class="dropdown-menu" role="menu">
- <li><a href="#">Action</a></li>
- <li><a href="#">Another action</a></li>
- <li><a href="#">Something else here</a></li>
- <li class="divider"></li>
- <li><a href="#">Separated link</a></li>
- </ul>
- </li>
- </ul>
- </div><!-- /.navbar-collapse -->
- </div><!-- /.container-fluid -->
- </nav>
-</header>
-
-
-
-
-
- The sidebar used in this page to the left provides an example of what your sidebar should like.
- Construction of a sidebar:
-
-
-<div class="main-sidebar">
- <!-- Inner sidebar -->
- <div class="sidebar">
- <!-- user panel (Optional) -->
- <div class="user-panel">
- <div class="pull-left image">
- <img src="dist/img/user2-160x160.jpg" class="img-circle" alt="User Image">
- </div>
- <div class="pull-left info">
- <p>User Name</p>
-
- <a href="#"><i class="fa fa-circle text-success"></i> Online</a>
- </div>
- </div><!-- /.user-panel -->
-
- <!-- Search Form (Optional) -->
- <form action="#" method="get" class="sidebar-form">
- <div class="input-group">
- <input type="text" name="q" class="form-control" placeholder="Search...">
- <span class="input-group-btn">
- <button type="submit" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i></button>
- </span>
- </div>
- </form><!-- /.sidebar-form -->
-
- <!-- Sidebar Menu -->
- <ul class="sidebar-menu">
- <li class="header">HEADER</li>
- <!-- Optionally, you can add icons to the links -->
- <li class="active"><a href="#"><span>Link</span></a><</li>
- <li><a href="#"><span>Another Link</span></a></li>
- <li class="treeview">
- <a href="#"><span>Multilevel</span> <i class="fa fa-angle-left pull-right"></i></a>
- <ul class="treeview-menu">
- <li><a href="#">Link in level 2</a></li>
- <li><a href="#">Link in level 2</a></li>
- </ul>
- </li>
- </ul><!-- /.sidebar-menu -->
-
- </div><!-- /.sidebar -->
-</div><!-- /.main-sidebar -->
-
-
- Control sidebar is the right side bar. It can be used for many purposes and is extremely easy
- to create. The sidebar ships with two different show/hide styles. The first allows the sidebar to
- slide over the content. The second pushes the content to make space for the sidebar. Either of
- these methods can be set through the Javascript options.
- The following code should be placed within the .wrapper
div. I prefer
- to place it right after the footer.
- Dark Sidebar Markup
-<!-- The Right Sidebar -->
-<aside class="control-sidebar control-sidebar-dark">
- <!-- Content of the sidebar goes here -->
-</aside>
-<!-- The sidebar's background -->
-<!-- This div must placed right after the sidebar for it to work-->
-<div class="control-sidebar-bg"></div>
-
- Light Sidebar Markup
-<!-- The Right Sidebar -->
-<aside class="control-sidebar control-sidebar-light">
- <!-- Content of the sidebar goes here -->
-</aside>
-<!-- The sidebar's background -->
-<!-- This div must placed right after the sidebar for it to work-->
-<div class="control-sidebar-bg"></div>
-
- Once you create the sidebar, you will need a toggle button to open/close it.
- By adding the attribute data-toggle="control-sidebar"
to any button, it will
- automatically act as the toggle button.
-
- Toggle Button Example
-
-
- Sidebar Toggle Markup
- <button class="btn btn-default" data-toggle="control-sidebar">Toggle Right Sidebar</button>
-
-
- Info Box
- Info boxes are used to display statistical snippets. There are two types of info boxes.
- First Type of Info Boxes
-
-
-
-
-
-
- Messages
- 1,410
-
-
-
-
-
-
-
- Bookmarks
- 410
-
-
-
-
-
-
-
- Uploads
- 13,648
-
-
-
-
-
- Markup
- <div class="info-box">
- <!-- Apply any bg-* class to to the icon to color it -->
- <span class="info-box-icon bg-red"><i class="fa fa-star-o"></i></span>
- <div class="info-box-content">
- <span class="info-box-text">Likes</span>
- <span class="info-box-number">93,139</span>
- </div><!-- /.info-box-content -->
-</div><!-- /.info-box -->
-
- Second Type of Info Boxes
-
-
-
-
-
-
Bookmarks
-
41,410
-
-
- 70% Increase in 30 Days
-
-
-
-
-
-
-
-
-
Likes
-
41,410
-
-
- 70% Increase in 30 Days
-
-
-
-
-
-
-
-
-
Events
-
41,410
-
-
- 70% Increase in 30 Days
-
-
-
-
-
-
-
-
-
Comments
-
41,410
-
-
- 70% Increase in 30 Days
-
-
-
-
-
- Markup
- <!-- Apply any bg-* class to to the info-box to color it -->
-<div class="info-box bg-red">
- <span class="info-box-icon"><i class="fa fa-comments-o"></i></span>
- <div class="info-box-content">
- <span class="info-box-text">Likes</span>
- <span class="info-box-number">41,410</span>
- <!-- The progress section is optional -->
- <div class="progress">
- <div class="progress-bar" style="width: 70%"></div>
- </div>
- <span class="progress-description">
- 70% Increase in 30 Days
- </span>
- </div><!-- /.info-box-content -->
-</div><!-- /.info-box -->
- The only thing you need to change to alternate between these style is change the placement of the bg-* class. For the
- first style apply any bg-* class to the icon itself. For the other style, apply the bg-* class to the info-box div.
-
-
- Box
- The box component is the most widely used component through out this template. You can
- use it for anything from displaying charts to just blocks of text. It comes in many different
- styles that we will explore below.
- Default Box Markup
-
-
-
- The body of the box
-
-
-
- <div class="box">
- <div class="box-header with-border">
- <h3 class="box-title">Default Box Example</h3>
- <div class="box-tools pull-right">
- <!-- Buttons, labels, and many other things can be placed here! -->
- <!-- Here is a label for example -->
- <span class="label label-primary">Label</span>
- </div><!-- /.box-tools -->
- </div><!-- /.box-header -->
- <div class="box-body">
- The body of the box
- </div><!-- /.box-body -->
- <div class="box-footer">
- The footer of the box
- </div><!-- box-footer -->
-</div><!-- /.box -->
- Box Variants
- You can change the style of the box by adding any of the contextual classes.
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
- <div class="box box-default">...</div>
-<div class="box box-primary">...</div>
-<div class="box box-info">...</div>
-<div class="box box-warning">...</div>
-<div class="box box-success">...</div>
-<div class="box box-danger">...</div>
-
- Solid Box
- Solid Boxes are alternative ways to display boxes.
- They can be created by simply adding the box-solid class to the box component.
- You may also use contextual classes with you solid boxes.
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-<div class="box box-solid box-default">...</div>
-<div class="box box-solid box-primary">...</div>
-<div class="box box-solid box-info">...</div>
-<div class="box box-solid box-warning">...</div>
-<div class="box box-solid box-success">...</div>
-<div class="box box-solid box-danger">...</div>
- Box Tools
- Boxes can contain tools to deploy a specific event or provide simple info. The following examples makes use
- of multiple AdminLTE components within the header of the box.
- AdminLTE data-widget attribute provides boxes with the ability to collapse or be removed. The buttons
- are placed in the box-tools which is placed in the box-header.
-
-<!-- This will cause the box to be removed when clicked -->
-<button class="btn btn-box-tool" data-widget="remove" data-toggle="tooltip" title="Remove"><i class="fa fa-times"></i></button>
-<!-- This will cause the box to collapse when clicked -->
-<button class="btn btn-box-tool" data-widget="collapse" data-toggle="tooltip" title="Collapse"><i class="fa fa-minus"></i></button>
-
-
-
-
-
- The body of the box
-
-
-
-<div class="box box-default">
- <div class="box-header with-border">
- <h3 class="box-title">Collapsable</h3>
- <div class="box-tools pull-right">
- <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
- </div><!-- /.box-tools -->
- </div><!-- /.box-header -->
- <div class="box-body">
- The body of the box
- </div><!-- /.box-body -->
-</div><!-- /.box -->
-
-
-
-
-
- The body of the box
-
-
-
-<div class="box box-default">
- <div class="box-header with-border">
- <h3 class="box-title">Removable</h3>
- <div class="box-tools pull-right">
- <button class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
- </div><!-- /.box-tools -->
- </div><!-- /.box-header -->
- <div class="box-body">
- The body of the box
- </div><!-- /.box-body -->
-</div><!-- /.box -->
-
-
-
-
-
- The body of the box
-
-
-
-<div class="box box-default collapsed-box">
- <div class="box-header with-border">
- <h3 class="box-title">Expandable</h3>
- <div class="box-tools pull-right">
- <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-plus"></i></button>
- </div><!-- /.box-tools -->
- </div><!-- /.box-header -->
- <div class="box-body">
- The body of the box
- </div><!-- /.box-body -->
-</div><!-- /.box -->
-
-
- We can also add labels, badges, pagination, tooltips, inputs and many more in the box tools. A few examples:
-
-
-
-
-
- The body of the box
-
-
-
-<div class="box box-default">
- <div class="box-header with-border">
- <h3 class="box-title">Labels</h3>
- <div class="box-tools pull-right">
- <span class="label label-default">8 New Messages</span>
- </div><!-- /.box-tools -->
- </div><!-- /.box-header -->
- <div class="box-body">
- The body of the box
- </div><!-- /.box-body -->
-</div><!-- /.box -->
-
-
-
-
-
- The body of the box
-
-
-
-<div class="box box-default">
- <div class="box-header with-border">
- <h3 class="box-title">Input</h3>
- <div class="box-tools pull-right">
- <div class="has-feedback">
- <input type="text" class="form-control input-sm" placeholder="Search...">
- <span class="glyphicon glyphicon-search form-control-feedback"></span>
- </div>
- </div><!-- /.box-tools -->
- </div><!-- /.box-header -->
- <div class="box-body">
- The body of the box
- </div><!-- /.box-body -->
-</div><!-- /.box -->
-
-
-
-
-
- The body of the box
-
-
-
-<div class="box box-default">
- <div class="box-header with-border">
- <h3 class="box-title">Tooltips on buttons</h3>
- <div class="box-tools pull-right">
- <button class="btn btn-box-tool" data-widget="collapse" data-toggle="tooltip" title="Collapse"><i class="fa fa-minus"></i></button>
- <button class="btn btn-box-tool" data-widget="remove" data-toggle="tooltip" title="Remove"><i class="fa fa-times"></i></button>
- </div><!-- /.box-tools -->
- </div><!-- /.box-header -->
- <div class="box-body">
- The body of the box
- </div><!-- /.box-body -->
-</div><!-- /.box -->
-
-
-
- If you inserted a box into the document after app.js
was loaded, you have to activate
- the collapse/remove buttons explicitly by calling .activateBox()
:
-
- <script>
- $("#box-widget").activateBox();
-</script>
-
- Loading States
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
-
-
- To simulate a loading state, simply place this code before the .box
closing tag.
-
- <div class="overlay">
- <i class="fa fa-refresh fa-spin"></i>
-</div>
-
- Direct Chat
- The direct chat widget extends the box component to create a beautiful chat interface. This widget
- consists of a required messages pane and an optional contacts pane. Examples:
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
- Direct Chat Markup
-
-<!-- Construct the box with style you want. Here we are using box-danger -->
-<!-- Then add the class direct-chat and choose the direct-chat-* contexual class -->
-<!-- The contextual class should match the box, so we are using direct-chat-danger -->
-<div class="box box-danger direct-chat direct-chat-danger">
- <div class="box-header with-border">
- <h3 class="box-title">Direct Chat</h3>
- <div class="box-tools pull-right">
- <span data-toggle="tooltip" title="3 New Messages" class="badge bg-red">3</span>
- <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
- <!-- In box-tools add this button if you intend to use the contacts pane -->
- <button class="btn btn-box-tool" data-toggle="tooltip" title="Contacts" data-widget="chat-pane-toggle"><i class="fa fa-comments"></i></button>
- <button class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
- </div>
- </div><!-- /.box-header -->
- <div class="box-body">
- <!-- Conversations are loaded here -->
- <div class="direct-chat-messages">
- <!-- Message. Default to the left -->
- <div class="direct-chat-msg">
- <div class="direct-chat-info clearfix">
- <span class="direct-chat-name pull-left">Alexander Pierce</span>
- <span class="direct-chat-timestamp pull-right">23 Jan 2:00 pm</span>
- </div><!-- /.direct-chat-info -->
- <img class="direct-chat-img" src="../dist/img/user1-128x128.jpg" alt="message user image"><!-- /.direct-chat-img -->
- <div class="direct-chat-text">
- Is this template really for free? That's unbelievable!
- </div><!-- /.direct-chat-text -->
- </div><!-- /.direct-chat-msg -->
-
- <!-- Message to the right -->
- <div class="direct-chat-msg right">
- <div class="direct-chat-info clearfix">
- <span class="direct-chat-name pull-right">Sarah Bullock</span>
- <span class="direct-chat-timestamp pull-left">23 Jan 2:05 pm</span>
- </div><!-- /.direct-chat-info -->
- <img class="direct-chat-img" src="../dist/img/user3-128x128.jpg" alt="message user image"><!-- /.direct-chat-img -->
- <div class="direct-chat-text">
- You better believe it!
- </div><!-- /.direct-chat-text -->
- </div><!-- /.direct-chat-msg -->
- </div><!--/.direct-chat-messages-->
-
- <!-- Contacts are loaded here -->
- <div class="direct-chat-contacts">
- <ul class="contacts-list">
- <li>
- <a href="#">
- <img class="contacts-list-img" src="../dist/img/user1-128x128.jpg" alt="Contact Avatar">
- <div class="contacts-list-info">
- <span class="contacts-list-name">
- Count Dracula
- <small class="contacts-list-date pull-right">2/28/2015</small>
- </span>
- <span class="contacts-list-msg">How have you been? I was...</span>
- </div><!-- /.contacts-list-info -->
- </a>
- </li><!-- End Contact Item -->
- </ul><!-- /.contatcts-list -->
- </div><!-- /.direct-chat-pane -->
- </div><!-- /.box-body -->
- <div class="box-footer">
- <div class="input-group">
- <input type="text" name="message" placeholder="Type Message ..." class="form-control">
- <span class="input-group-btn">
- <button type="button" class="btn btn-danger btn-flat">Send</button>
- </span>
- </div>
- </div><!-- /.box-footer-->
-</div><!--/.direct-chat -->
-
-
- Of course you can use direct chat with a solid box by adding the class solid-box
to the box. Here are a couple of examples:
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/dependencies.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/dependencies.html
deleted file mode 100644
index 495e907..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/dependencies.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- AdminLTE depends on two main frameworks.
- The downloadable package contains both of these libraries, so you don't have to manually download them.
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/download.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/download.html
deleted file mode 100644
index fa034ea..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/download.html
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
- AdminLTE can be downloaded in two different versions, each appealing to different skill levels and use case.
-
-
-
-
-
-
-
Compiled and ready to use in production. Download this version if you don't want to customize AdminLTE's LESS files.
-
Download
-
-
-
-
-
-
-
-
All files including the compiled CSS. Download this version if you plan on customizing the template. Requires a LESS compiler.
-
Download
-
-
-
-
- File Hierarchy of the Source Code Package
-
-AdminLTE/
-├── dist/
-│ ├── CSS/
-│ ├── JS
-│ ├── img
-├── build/
-│ ├── less/
-│ │ ├── AdminLTE's Less files
-│ └── Bootstrap-less/ (Only for reference. No modifications have been made)
-│ ├── mixins/
-│ ├── variables.less
-│ ├── mixins.less
-└── plugins/
- ├── All the customized plugins CSS and JS files
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/faq.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/faq.html
deleted file mode 100644
index 203cbee..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/faq.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- Can AdminLTE be used with Wordpress?
- AdminLTE is an HTML template that can be used for any purpose. However, it is not made to be easily installed on Wordpress. It will require some effort and enough knowledge of the Wordpress script to do so.
-
- Is there an integration guide for PHP frameworks such as Yii or Symfony?
- Short answer, no. However, there are forks and tutorials around the web that provide info on how to integrate with many different frameworks. There are even versions of AdminLTE that are integrated with jQuery ajax, AngularJS and/or MVC5 ASP .NET.
-
- How do I get notified of new AdminLTE versions?
- The best option is to subscribe to our mailing list using the subscription form on Almsaeed Studio.
- If that's not appealing to you, you may watch the repository on Github or visit Almsaeed Studio every now and then for updates and announcements.
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/implementations.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/implementations.html
deleted file mode 100644
index b2f0d18..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/implementations.html
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
- Thanks to many of AdminLTE users, there are multiple implementations of the template
- for easy integration with back-end frameworks. The following are some of them:
-
-
-
- Note: these implementations are not supported by Almsaeed Studio. However,
- they do provide a good example of how to integrate AdminLTE into different frameworks. For the latest release
- of AdminLTE, please visit our repository or website
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/introduction.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/introduction.html
deleted file mode 100644
index 3a88850..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/introduction.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
- AdminLTE is a popular open source WebApp template for admin dashboards and control panels.
- It is a responsive HTML template that is based on the CSS framework Bootstrap 3.
- It utilizes all of the Bootstrap components in its design and re-styles many
- commonly used plugins to create a consistent design that can be used as a user
- interface for backend applications. AdminLTE is based on a modular design, which
- allows it to be easily customized and built upon. This documentation will guide you through
- installing the template and exploring the various components that are bundled with the template.
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/layout.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/layout.html
deleted file mode 100644
index 064c7bf..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/layout.html
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
- The layout consists of four major parts:
-
- - Wrapper
.wrapper
. A div that wraps the whole site.
- - Main Header
.main-header
. Contains the logo and navbar.
- - Sidebar
.sidebar-wrapper
. Contains the user panel and sidebar menu.
- - Content
.content-wrapper
. Contains the page header and content.
-
-
-
Tip!
-
The starter page is a good place to start building your app if you'd like to start from scratch.
-
-
- Layout Options
- AdminLTE 2.0 provides a set of options to apply to your main layout. Each one of these classes can be added
- to the body tag to get the desired goal.
-
- - Fixed: use the class
.fixed
to get a fixed header and sidebar.
- - Collapsed Sidebar: use the class
.sidebar-collapse
to have a collapsed sidebar upon loading.
- - Boxed Layout: use the class
.layout-boxed
to get a boxed layout that stretches only to 1250px.
- - Top Navigation use the class
.layout-top-nav
to remove the sidebar and have your links at the top navbar.
-
- Note: you cannot use both layout-boxed and fixed at the same time. Anything else can be mixed together.
-
- Skins
- Skins can be found in the dist/css/skins folder.
- Choose the skin file that you want and then add the appropriate
- class to the body tag to change the template's appearance. Here is the list of available skins:
-
-
-
-
-
- Skin Class |
- Preview |
-
-
-
-
- skin-blue |
- |
-
-
- skin-blue-light |
- |
-
-
- skin-yellow |
- |
-
-
- skin-yellow-light |
- |
-
-
- skin-green |
- |
-
-
- skin-green-light |
- |
-
-
- skin-purple |
- |
-
-
- skin-purple-light |
- |
-
-
- skin-red |
- |
-
-
- skin-red-light |
- |
-
-
- skin-black |
- |
-
-
- skin-black-light |
- |
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/license.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/license.html
deleted file mode 100644
index b326240..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/license.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- AdminLTE
-
- AdminLTE is an open source project that is licensed under the MIT license.
- This allows you to do pretty much anything you want as long as you include
- the copyright in "all copies or substantial portions of the Software."
- Attribution is not required (though very much appreciated).
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/plugins.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/plugins.html
deleted file mode 100644
index eb9c66f..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/plugins.html
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
- AdminLTE makes use of the following plugins. For documentation, updates or license information, please visit the provided links.
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/upgrade.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/upgrade.html
deleted file mode 100644
index d339bc6..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/include/upgrade.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
- To upgrade from version 1.x to the lateset version, follow this guide.
- New Files
- Make sure you update all CSS and JS files that are related to AdminLTE. Otherwise, the layout will not
- function properly. Most important files are AdminLTE.css, skins CSS files, and app.js.
- Layout Changes
-
- - The .wrapper div must be placed immediately after the body tag rather than after the header
- - Change the .header div to .main-header
<div class="main-header">
- - Change the .right-side class to .content-wrapper
<div class="content-wrapper">
- - Change the .left-side class to .main-sidebar
<div class="main-sidebar">
- - In the navbar, change .navbar-right to .navbar-custom-menu
<div class="navbar-custom-menu">
-
- Navbar Custom Dropdown Menus
-
- - The icons in the notification menu do not need bg-* classes. They should be replaced with contextual text color class such as text-aqua or text-red.
-
- Login, Registration and Lockscreen Pages
- There are major changes to the HTML markup and style to these pages. The best way is to copy the page's code and customize it.
- And you should be set to go!
- Mailbox
- Mailbox got an upgrade to include three different views. The views are inbox, read mail, and compose new email. To use these views,
- you should use the provided HTML files in the pages/mailbox folder.
- Note: the old mailbox layout has been deprecated in favor of the new one and will be removed by the next release.
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/index.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/index.html
deleted file mode 100644
index 4322582..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/build/index.html
+++ /dev/null
@@ -1,201 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- This documentation is for versions 2.3 and under.
- If you are looking for documentation for version 2.4 and above,
- please visit our online documentation.
-
-
- include "introduction.html"
-
-
-
- include "download.html"
-
-
-
- include "dependencies.html"
-
-
-
- include "advice.html"
-
-
-
- include "layout.html"
-
-
-
- include "adminlte-options.html"
-
-
-
- include "components.html"
-
-
-
- include "plugins.html"
-
-
-
- include "browsers.html"
-
-
-
- include "upgrade.html"
-
-
-
- include "implementations.html"
-
-
-
- include "faq.html"
-
-
-
- include "license.html"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/docs.js b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/docs.js
deleted file mode 100644
index cbbe38b..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/docs.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Documentation JS script
- */
-$(function () {
- 'use strict'
-
- var $slideToTop = $('')
-
- $slideToTop.html('')
-
- $slideToTop.css({
- position : 'fixed',
- bottom : '20px',
- right : '25px',
- width : '40px',
- height : '40px',
- color : '#eee',
- 'font-size' : '',
- 'line-height' : '40px',
- 'text-align' : 'center',
- 'background-color': '#222d32',
- cursor : 'pointer',
- 'border-radius' : '5px',
- 'z-index' : '99999',
- opacity : '.7',
- 'display' : 'none'
- })
-
- $slideToTop.on('mouseenter', function () {
- $(this).css('opacity', '1')
- })
-
- $slideToTop.on('mouseout', function () {
- $(this).css('opacity', '.7')
- })
-
- $('.wrapper').append($slideToTop)
-
- $(window).scroll(function () {
- if ($(window).scrollTop() >= 150) {
- if (!$($slideToTop).is(':visible')) {
- $($slideToTop).fadeIn(500)
- }
- } else {
- $($slideToTop).fadeOut(500)
- }
- })
-
- $($slideToTop).click(function () {
- $('body').animate({
- scrollTop: 0
- }, 500)
- })
-
- $('.sidebar-menu li:not(.treeview) a').click(function () {
- var $this = $(this)
- var target = $this.attr('href')
- if (typeof target === 'string') {
- $('body').animate({
- scrollTop: ($(target).offset().top) + 'px'
- }, 500)
- }
- })
- // Skin switcher
- var currentSkin = 'skin-blue'
-
- $('#layout-skins-list [data-skin]').click(function (e) {
- e.preventDefault()
- var skinName = $(this).data('skin')
- $('body').removeClass(currentSkin)
- $('body').addClass(skinName)
- currentSkin = skinName
- })
-})
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/index.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/index.html
deleted file mode 100644
index 3acbdac..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/index.html
+++ /dev/null
@@ -1,2178 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- This documentation is for versions 2.3 and under.
- If you are looking for documentation for version 2.4 and above,
- please visit our online documentation.
-
-
-
-
-
- AdminLTE is a popular open source WebApp template for admin dashboards and control panels.
- It is a responsive HTML template that is based on the CSS framework Bootstrap 3.
- It utilizes all of the Bootstrap components in its design and re-styles many
- commonly used plugins to create a consistent design that can be used as a user
- interface for backend applications. AdminLTE is based on a modular design, which
- allows it to be easily customized and built upon. This documentation will guide you through
- installing the template and exploring the various components that are bundled with the template.
-
-
-
-
-
-
-
-
-
- AdminLTE can be downloaded in two different versions, each appealing to different skill levels and use case.
-
-
-
-
-
-
-
Compiled and ready to use in production. Download this version if you don't want to customize AdminLTE's LESS files.
-
Download
-
-
-
-
-
-
-
-
All files including the compiled CSS. Download this version if you plan on customizing the template. Requires a LESS compiler.
-
Download
-
-
-
-
- File Hierarchy of the Source Code Package
-
- AdminLTE/
- ├── dist/
- │ ├── CSS/
- │ ├── JS
- │ ├── img
- ├── build/
- │ ├── less/
- │ │ ├── AdminLTE's Less files
- │ └── Bootstrap-less/ (Only for reference. No modifications have been made)
- │ ├── mixins/
- │ ├── variables.less
- │ ├── mixins.less
- └── plugins/
- ├── All the customized plugins CSS and JS files
-
-
-
-
-
-
-
- AdminLTE depends on two main frameworks.
- The downloadable package contains both of these libraries, so you don't have to manually download them.
-
-
-
-
-
-
-
-
-
- Before you go to see your new awesome theme, here are few tips on how to familiarize yourself with it:
-
-
-
- - AdminLTE is based on Bootstrap 3. If you are unfamiliar with Bootstrap, visit their website and read through the documentation. All of Bootstrap components have been modified to fit the style of AdminLTE and provide a consistent look throughout the template. This way, we guarantee you will get the best of AdminLTE.
- - Go through the pages that are bundled with the theme. Most of the template example pages contain quick tips on how to create or use a component which can be really helpful when you need to create something on the fly.
- - Documentation. We are trying our best to make your experience with AdminLTE be smooth. One way to achieve that is to provide documentation and support. If you think that something is missing from the documentation, please do not hesitate to create an issue to tell us about it.
- - Built with LESS. This theme uses the LESS compiler to make it easier to customize and use. LESS is easy to learn if you know CSS or SASS. It is not necessary to learn LESS but it will benefit you a lot in the future.
- - Hosted on GitHub. Visit our GitHub repository to view issues, make requests, or contribute to the project.
-
-
- Note: LESS files are better commented than the compiled CSS file.
-
-
-
-
-
-
-
-
- The layout consists of four major parts:
-
- - Wrapper
.wrapper
. A div that wraps the whole site.
- - Main Header
.main-header
. Contains the logo and navbar.
- - Sidebar
.sidebar-wrapper
. Contains the user panel and sidebar menu.
- - Content
.content-wrapper
. Contains the page header and content.
-
-
-
Tip!
-
The starter page is a good place to start building your app if you'd like to start from scratch.
-
-
- Layout Options
- AdminLTE 2.0 provides a set of options to apply to your main layout. Each one of these classes can be added
- to the body tag to get the desired goal.
-
- - Fixed: use the class
.fixed
to get a fixed header and sidebar.
- - Collapsed Sidebar: use the class
.sidebar-collapse
to have a collapsed sidebar upon loading.
- - Boxed Layout: use the class
.layout-boxed
to get a boxed layout that stretches only to 1250px.
- - Top Navigation use the class
.layout-top-nav
to remove the sidebar and have your links at the top navbar.
-
- Note: you cannot use both layout-boxed and fixed at the same time. Anything else can be mixed together.
-
- Skins
- Skins can be found in the dist/css/skins folder.
- Choose the skin file that you want and then add the appropriate
- class to the body tag to change the template's appearance. Here is the list of available skins:
-
-
-
-
-
- Skin Class |
- Preview |
-
-
-
-
- skin-blue |
- |
-
-
- skin-blue-light |
- |
-
-
- skin-yellow |
- |
-
-
- skin-yellow-light |
- |
-
-
- skin-green |
- |
-
-
- skin-green-light |
- |
-
-
- skin-purple |
- |
-
-
- skin-purple-light |
- |
-
-
- skin-red |
- |
-
-
- skin-red-light |
- |
-
-
- skin-black |
- |
-
-
- skin-black-light |
- |
-
-
-
-
-
-
-
-
-
-
-
-
- Modifying the options of AdminLTE's app.js can be done using one of the following ways.
-
- Editing app.js
- Within the main Javascript file, modify the $.AdminLTE.options
object to suit your use case.
-
- Defining AdminLTEOptions
- Alternatively, you can define a global options variable named AdminLTEOptions
and initialize it before loading app.js.
- Example
- <script>
- var AdminLTEOptions = {
- //Enable sidebar expand on hover effect for sidebar mini
- //This option is forced to true if both the fixed layout and sidebar mini
- //are used together
- sidebarExpandOnHover: true,
- //BoxRefresh Plugin
- enableBoxRefresh: true,
- //Bootstrap.js tooltip
- enableBSToppltip: true
- };
- </script>
- <script src="dist/js/app.js" type="text/javascript"></script>
-
- Available AdminLTE Options
- {
- //Add slimscroll to navbar menus
- //This requires you to load the slimscroll plugin
- //in every page before app.js
- navbarMenuSlimscroll: true,
- navbarMenuSlimscrollWidth: "3px", //The width of the scroll bar
- navbarMenuHeight: "200px", //The height of the inner menu
- //General animation speed for JS animated elements such as box collapse/expand and
- //sidebar treeview slide up/down. This option accepts an integer as milliseconds,
- //'fast', 'normal', or 'slow'
- animationSpeed: 500,
- //Sidebar push menu toggle button selector
- sidebarToggleSelector: "[data-toggle='offcanvas']",
- //Activate sidebar push menu
- sidebarPushMenu: true,
- //Activate sidebar slimscroll if the fixed layout is set (requires SlimScroll Plugin)
- sidebarSlimScroll: true,
- //Enable sidebar expand on hover effect for sidebar mini
- //This option is forced to true if both the fixed layout and sidebar mini
- //are used together
- sidebarExpandOnHover: false,
- //BoxRefresh Plugin
- enableBoxRefresh: true,
- //Bootstrap.js tooltip
- enableBSToppltip: true,
- BSTooltipSelector: "[data-toggle='tooltip']",
- //Enable Fast Click. Fastclick.js creates a more
- //native touch experience with touch devices. If you
- //choose to enable the plugin, make sure you load the script
- //before AdminLTE's app.js
- enableFastclick: true,
- //Control Sidebar Tree Views
- enableControlTreeView: true,
- //Control Sidebar Options
- enableControlSidebar: true,
- controlSidebarOptions: {
- //Which button should trigger the open/close event
- toggleBtnSelector: "[data-toggle='control-sidebar']",
- //The sidebar selector
- selector: ".control-sidebar",
- //Enable slide over content
- slide: true
- },
- //Box Widget Plugin. Enable this plugin
- //to allow boxes to be collapsed and/or removed
- enableBoxWidget: true,
- //Box Widget plugin options
- boxWidgetOptions: {
- boxWidgetIcons: {
- //Collapse icon
- collapse: 'fa-minus',
- //Open icon
- open: 'fa-plus',
- //Remove icon
- remove: 'fa-times'
- },
- boxWidgetSelectors: {
- //Remove button selector
- remove: '[data-widget="remove"]',
- //Collapse button selector
- collapse: '[data-widget="collapse"]'
- }
- },
- //Direct Chat plugin options
- directChat: {
- //Enable direct chat by default
- enable: true,
- //The button to open and close the chat contacts pane
- contactToggleSelector: '[data-widget="chat-pane-toggle"]'
- },
- //Define the set of colors to use globally around the website
- colors: {
- lightBlue: "#3c8dbc",
- red: "#f56954",
- green: "#00a65a",
- aqua: "#00c0ef",
- yellow: "#f39c12",
- blue: "#0073b7",
- navy: "#001F3F",
- teal: "#39CCCC",
- olive: "#3D9970",
- lime: "#01FF70",
- orange: "#FF851B",
- fuchsia: "#F012BE",
- purple: "#8E24AA",
- maroon: "#D81B60",
- black: "#222222",
- gray: "#d2d6de"
- },
- //The standard screen sizes that bootstrap uses.
- //If you change these in the variables.less file, change
- //them here too.
- screenSizes: {
- xs: 480,
- sm: 768,
- md: 992,
- lg: 1200
- }
- }
-
-
-
-
-
-
-
-
-
Reminder!
-
- AdminLTE uses all of Bootstrap 3 components. It's a good start to review
- the Bootstrap documentation to get an idea of the various components
- that this documentation does not cover.
-
-
-
-
Tip!
-
- If you go through the example pages and would like to copy a component, right-click on
- the component and choose "inspect element" to get to the HTML quicker than scanning
- the HTML page.
-
-
- Main Header
- The main header contains the logo and navbar. Construction of the
- navbar differs slightly from Bootstrap because it has components that Bootstrap doesn't provide.
- The navbar can be constructed in two ways. This is an example for the normal navbar and next we will provide an example for
- the top nav layout.
-
-
-
Main Header Example
-
-
- AdminLTE
-
-
-
-
-
- <header class="main-header">
- <a href="../../index2.html" class="logo">
- <!-- LOGO -->
- AdminLTE
- </a>
- <!-- Header Navbar: style can be found in header.less -->
- <nav class="navbar navbar-static-top" role="navigation">
- <!-- Navbar Right Menu -->
- <div class="navbar-custom-menu">
- <ul class="nav navbar-nav">
- <!-- Messages: style can be found in dropdown.less-->
- <li class="dropdown messages-menu">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">
- <i class="fa fa-envelope-o"></i>
- <span class="label label-success">4</span>
- </a>
- <ul class="dropdown-menu">
- <li class="header">You have 4 messages</li>
- <li>
- <!-- inner menu: contains the actual data -->
- <ul class="menu">
- <li><!-- start message -->
- <a href="#">
- <div class="pull-left">
- <img src="dist/img/user2-160x160.jpg" class="img-circle" alt="User Image">
- </div>
- <h4>
- Sender Name
- <small><i class="fa fa-clock-o"></i> 5 mins</small>
- </h4>
- <p>Message Excerpt</p>
- </a>
- </li><!-- end message -->
- ...
- </ul>
- </li>
- <li class="footer"><a href="#">See All Messages</a></li>
- </ul>
- </li>
- <!-- Notifications: style can be found in dropdown.less -->
- <li class="dropdown notifications-menu">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">
- <i class="fa fa-bell-o"></i>
- <span class="label label-warning">10</span>
- </a>
- <ul class="dropdown-menu">
- <li class="header">You have 10 notifications</li>
- <li>
- <!-- inner menu: contains the actual data -->
- <ul class="menu">
- <li>
- <a href="#">
- <i class="ion ion-ios-people info"></i> Notification title
- </a>
- </li>
- ...
- </ul>
- </li>
- <li class="footer"><a href="#">View all</a></li>
- </ul>
- </li>
- <!-- Tasks: style can be found in dropdown.less -->
- <li class="dropdown tasks-menu">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">
- <i class="fa fa-flag-o"></i>
- <span class="label label-danger">9</span>
- </a>
- <ul class="dropdown-menu">
- <li class="header">You have 9 tasks</li>
- <li>
- <!-- inner menu: contains the actual data -->
- <ul class="menu">
- <li><!-- Task item -->
- <a href="#">
- <h3>
- Design some buttons
- <small class="pull-right">20%</small>
- </h3>
- <div class="progress xs">
- <div class="progress-bar progress-bar-aqua" style="width: 20%" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100">
- <span class="sr-only">20% Complete</span>
- </div>
- </div>
- </a>
- </li><!-- end task item -->
- ...
- </ul>
- </li>
- <li class="footer">
- <a href="#">View all tasks</a>
- </li>
- </ul>
- </li>
- <!-- User Account: style can be found in dropdown.less -->
- <li class="dropdown user user-menu">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">
- <img src="dist/img/user2-160x160.jpg" class="user-image" alt="User Image">
- <span class="hidden-xs">Alexander Pierce</span>
- </a>
- <ul class="dropdown-menu">
- <!-- User image -->
- <li class="user-header">
- <img src="dist/img/user2-160x160.jpg" class="img-circle" alt="User Image">
- <p>
- Alexander Pierce - Web Developer
- <small>Member since Nov. 2012</small>
- </p>
- </li>
- <!-- Menu Body -->
- <li class="user-body">
- <div class="col-xs-4 text-center">
- <a href="#">Followers</a>
- </div>
- <div class="col-xs-4 text-center">
- <a href="#">Sales</a>
- </div>
- <div class="col-xs-4 text-center">
- <a href="#">Friends</a>
- </div>
- </li>
- <!-- Menu Footer-->
- <li class="user-footer">
- <div class="pull-left">
- <a href="#" class="btn btn-default btn-flat">Profile</a>
- </div>
- <div class="pull-right">
- <a href="#" class="btn btn-default btn-flat">Sign out</a>
- </div>
- </li>
- </ul>
- </li>
- </ul>
- </div>
- </nav>
- </header>
- Top Nav Layout. Main Header Example.
-
-
Reminder!
-
To use this main header instead of the regular one, you must add the layout-top-nav
class to the body tag.
-
-
-
- <header class="main-header">
- <nav class="navbar navbar-static-top">
- <div class="container-fluid">
- <div class="navbar-header">
- <a href="../../index2.html" class="navbar-brand"><b>Admin</b>LTE</a>
- <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse">
- <i class="fa fa-bars"></i>
- </button>
- </div>
-
- <!-- Collect the nav links, forms, and other content for toggling -->
- <div class="collapse navbar-collapse" id="navbar-collapse">
- <ul class="nav navbar-nav">
- <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
- <li><a href="#">Link</a></li>
- <li class="dropdown">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
- <ul class="dropdown-menu" role="menu">
- <li><a href="#">Action</a></li>
- <li><a href="#">Another action</a></li>
- <li><a href="#">Something else here</a></li>
- <li class="divider"></li>
- <li><a href="#">Separated link</a></li>
- <li class="divider"></li>
- <li><a href="#">One more separated link</a></li>
- </ul>
- </li>
- </ul>
- <form class="navbar-form navbar-left" role="search">
- <div class="form-group">
- <input type="text" class="form-control" id="navbar-search-input" placeholder="Search">
- </div>
- </form>
- <ul class="nav navbar-nav navbar-right">
- <li><a href="#">Link</a></li>
- <li class="dropdown">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
- <ul class="dropdown-menu" role="menu">
- <li><a href="#">Action</a></li>
- <li><a href="#">Another action</a></li>
- <li><a href="#">Something else here</a></li>
- <li class="divider"></li>
- <li><a href="#">Separated link</a></li>
- </ul>
- </li>
- </ul>
- </div><!-- /.navbar-collapse -->
- </div><!-- /.container-fluid -->
- </nav>
- </header>
-
-
-
-
-
- The sidebar used in this page to the left provides an example of what your sidebar should like.
- Construction of a sidebar:
-
-
- <div class="main-sidebar">
- <!-- Inner sidebar -->
- <div class="sidebar">
- <!-- user panel (Optional) -->
- <div class="user-panel">
- <div class="pull-left image">
- <img src="dist/img/user2-160x160.jpg" class="img-circle" alt="User Image">
- </div>
- <div class="pull-left info">
- <p>User Name</p>
-
- <a href="#"><i class="fa fa-circle text-success"></i> Online</a>
- </div>
- </div><!-- /.user-panel -->
-
- <!-- Search Form (Optional) -->
- <form action="#" method="get" class="sidebar-form">
- <div class="input-group">
- <input type="text" name="q" class="form-control" placeholder="Search...">
- <span class="input-group-btn">
- <button type="submit" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i></button>
- </span>
- </div>
- </form><!-- /.sidebar-form -->
-
- <!-- Sidebar Menu -->
- <ul class="sidebar-menu">
- <li class="header">HEADER</li>
- <!-- Optionally, you can add icons to the links -->
- <li class="active"><a href="#"><span>Link</span></a><</li>
- <li><a href="#"><span>Another Link</span></a></li>
- <li class="treeview">
- <a href="#"><span>Multilevel</span> <i class="fa fa-angle-left pull-right"></i></a>
- <ul class="treeview-menu">
- <li><a href="#">Link in level 2</a></li>
- <li><a href="#">Link in level 2</a></li>
- </ul>
- </li>
- </ul><!-- /.sidebar-menu -->
-
- </div><!-- /.sidebar -->
- </div><!-- /.main-sidebar -->
-
-
- Control sidebar is the right side bar. It can be used for many purposes and is extremely easy
- to create. The sidebar ships with two different show/hide styles. The first allows the sidebar to
- slide over the content. The second pushes the content to make space for the sidebar. Either of
- these methods can be set through the Javascript options.
- The following code should be placed within the .wrapper
div. I prefer
- to place it right after the footer.
- Dark Sidebar Markup
- <!-- The Right Sidebar -->
- <aside class="control-sidebar control-sidebar-dark">
- <!-- Content of the sidebar goes here -->
- </aside>
- <!-- The sidebar's background -->
- <!-- This div must placed right after the sidebar for it to work-->
- <div class="control-sidebar-bg"></div>
-
- Light Sidebar Markup
- <!-- The Right Sidebar -->
- <aside class="control-sidebar control-sidebar-light">
- <!-- Content of the sidebar goes here -->
- </aside>
- <!-- The sidebar's background -->
- <!-- This div must placed right after the sidebar for it to work-->
- <div class="control-sidebar-bg"></div>
-
- Once you create the sidebar, you will need a toggle button to open/close it.
- By adding the attribute data-toggle="control-sidebar"
to any button, it will
- automatically act as the toggle button.
-
- Toggle Button Example
-
-
- Sidebar Toggle Markup
- <button class="btn btn-default" data-toggle="control-sidebar">Toggle Right Sidebar</button>
-
-
- Info Box
- Info boxes are used to display statistical snippets. There are two types of info boxes.
- First Type of Info Boxes
-
-
-
-
-
-
- Messages
- 1,410
-
-
-
-
-
-
-
- Bookmarks
- 410
-
-
-
-
-
-
-
- Uploads
- 13,648
-
-
-
-
-
- Markup
- <div class="info-box">
- <!-- Apply any bg-* class to to the icon to color it -->
- <span class="info-box-icon bg-red"><i class="fa fa-star-o"></i></span>
- <div class="info-box-content">
- <span class="info-box-text">Likes</span>
- <span class="info-box-number">93,139</span>
- </div><!-- /.info-box-content -->
- </div><!-- /.info-box -->
-
- Second Type of Info Boxes
-
-
-
-
-
-
Bookmarks
-
41,410
-
-
- 70% Increase in 30 Days
-
-
-
-
-
-
-
-
-
Likes
-
41,410
-
-
- 70% Increase in 30 Days
-
-
-
-
-
-
-
-
-
Events
-
41,410
-
-
- 70% Increase in 30 Days
-
-
-
-
-
-
-
-
-
Comments
-
41,410
-
-
- 70% Increase in 30 Days
-
-
-
-
-
- Markup
- <!-- Apply any bg-* class to to the info-box to color it -->
- <div class="info-box bg-red">
- <span class="info-box-icon"><i class="fa fa-comments-o"></i></span>
- <div class="info-box-content">
- <span class="info-box-text">Likes</span>
- <span class="info-box-number">41,410</span>
- <!-- The progress section is optional -->
- <div class="progress">
- <div class="progress-bar" style="width: 70%"></div>
- </div>
- <span class="progress-description">
- 70% Increase in 30 Days
- </span>
- </div><!-- /.info-box-content -->
- </div><!-- /.info-box -->
- The only thing you need to change to alternate between these style is change the placement of the bg-* class. For the
- first style apply any bg-* class to the icon itself. For the other style, apply the bg-* class to the info-box div.
-
-
- Box
- The box component is the most widely used component through out this template. You can
- use it for anything from displaying charts to just blocks of text. It comes in many different
- styles that we will explore below.
- Default Box Markup
-
-
-
- The body of the box
-
-
-
- <div class="box">
- <div class="box-header with-border">
- <h3 class="box-title">Default Box Example</h3>
- <div class="box-tools pull-right">
- <!-- Buttons, labels, and many other things can be placed here! -->
- <!-- Here is a label for example -->
- <span class="label label-primary">Label</span>
- </div><!-- /.box-tools -->
- </div><!-- /.box-header -->
- <div class="box-body">
- The body of the box
- </div><!-- /.box-body -->
- <div class="box-footer">
- The footer of the box
- </div><!-- box-footer -->
- </div><!-- /.box -->
- Box Variants
- You can change the style of the box by adding any of the contextual classes.
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
- <div class="box box-default">...</div>
- <div class="box box-primary">...</div>
- <div class="box box-info">...</div>
- <div class="box box-warning">...</div>
- <div class="box box-success">...</div>
- <div class="box box-danger">...</div>
-
- Solid Box
- Solid Boxes are alternative ways to display boxes.
- They can be created by simply adding the box-solid class to the box component.
- You may also use contextual classes with you solid boxes.
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
- <div class="box box-solid box-default">...</div>
- <div class="box box-solid box-primary">...</div>
- <div class="box box-solid box-info">...</div>
- <div class="box box-solid box-warning">...</div>
- <div class="box box-solid box-success">...</div>
- <div class="box box-solid box-danger">...</div>
- Box Tools
- Boxes can contain tools to deploy a specific event or provide simple info. The following examples makes use
- of multiple AdminLTE components within the header of the box.
- AdminLTE data-widget attribute provides boxes with the ability to collapse or be removed. The buttons
- are placed in the box-tools which is placed in the box-header.
-
- <!-- This will cause the box to be removed when clicked -->
- <button class="btn btn-box-tool" data-widget="remove" data-toggle="tooltip" title="Remove"><i class="fa fa-times"></i></button>
- <!-- This will cause the box to collapse when clicked -->
- <button class="btn btn-box-tool" data-widget="collapse" data-toggle="tooltip" title="Collapse"><i class="fa fa-minus"></i></button>
-
-
-
-
-
- The body of the box
-
-
-
- <div class="box box-default">
- <div class="box-header with-border">
- <h3 class="box-title">Collapsable</h3>
- <div class="box-tools pull-right">
- <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
- </div><!-- /.box-tools -->
- </div><!-- /.box-header -->
- <div class="box-body">
- The body of the box
- </div><!-- /.box-body -->
- </div><!-- /.box -->
-
-
-
-
-
- The body of the box
-
-
-
- <div class="box box-default">
- <div class="box-header with-border">
- <h3 class="box-title">Removable</h3>
- <div class="box-tools pull-right">
- <button class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
- </div><!-- /.box-tools -->
- </div><!-- /.box-header -->
- <div class="box-body">
- The body of the box
- </div><!-- /.box-body -->
- </div><!-- /.box -->
-
-
-
-
-
- The body of the box
-
-
-
- <div class="box box-default collapsed-box">
- <div class="box-header with-border">
- <h3 class="box-title">Expandable</h3>
- <div class="box-tools pull-right">
- <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-plus"></i></button>
- </div><!-- /.box-tools -->
- </div><!-- /.box-header -->
- <div class="box-body">
- The body of the box
- </div><!-- /.box-body -->
- </div><!-- /.box -->
-
-
- We can also add labels, badges, pagination, tooltips, inputs and many more in the box tools. A few examples:
-
-
-
-
-
- The body of the box
-
-
-
- <div class="box box-default">
- <div class="box-header with-border">
- <h3 class="box-title">Labels</h3>
- <div class="box-tools pull-right">
- <span class="label label-default">8 New Messages</span>
- </div><!-- /.box-tools -->
- </div><!-- /.box-header -->
- <div class="box-body">
- The body of the box
- </div><!-- /.box-body -->
- </div><!-- /.box -->
-
-
-
-
-
- The body of the box
-
-
-
- <div class="box box-default">
- <div class="box-header with-border">
- <h3 class="box-title">Input</h3>
- <div class="box-tools pull-right">
- <div class="has-feedback">
- <input type="text" class="form-control input-sm" placeholder="Search...">
- <span class="glyphicon glyphicon-search form-control-feedback"></span>
- </div>
- </div><!-- /.box-tools -->
- </div><!-- /.box-header -->
- <div class="box-body">
- The body of the box
- </div><!-- /.box-body -->
- </div><!-- /.box -->
-
-
-
-
-
- The body of the box
-
-
-
- <div class="box box-default">
- <div class="box-header with-border">
- <h3 class="box-title">Tooltips on buttons</h3>
- <div class="box-tools pull-right">
- <button class="btn btn-box-tool" data-widget="collapse" data-toggle="tooltip" title="Collapse"><i class="fa fa-minus"></i></button>
- <button class="btn btn-box-tool" data-widget="remove" data-toggle="tooltip" title="Remove"><i class="fa fa-times"></i></button>
- </div><!-- /.box-tools -->
- </div><!-- /.box-header -->
- <div class="box-body">
- The body of the box
- </div><!-- /.box-body -->
- </div><!-- /.box -->
-
-
-
- If you inserted a box into the document after app.js
was loaded, you have to activate
- the collapse/remove buttons explicitly by calling .activateBox()
:
-
- <script>
- $("#box-widget").activateBox();
- </script>
-
- Loading States
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
-
-
- To simulate a loading state, simply place this code before the .box
closing tag.
-
- <div class="overlay">
- <i class="fa fa-refresh fa-spin"></i>
- </div>
-
- Direct Chat
- The direct chat widget extends the box component to create a beautiful chat interface. This widget
- consists of a required messages pane and an optional contacts pane. Examples:
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
- Direct Chat Markup
-
- <!-- Construct the box with style you want. Here we are using box-danger -->
- <!-- Then add the class direct-chat and choose the direct-chat-* contexual class -->
- <!-- The contextual class should match the box, so we are using direct-chat-danger -->
- <div class="box box-danger direct-chat direct-chat-danger">
- <div class="box-header with-border">
- <h3 class="box-title">Direct Chat</h3>
- <div class="box-tools pull-right">
- <span data-toggle="tooltip" title="3 New Messages" class="badge bg-red">3</span>
- <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
- <!-- In box-tools add this button if you intend to use the contacts pane -->
- <button class="btn btn-box-tool" data-toggle="tooltip" title="Contacts" data-widget="chat-pane-toggle"><i class="fa fa-comments"></i></button>
- <button class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
- </div>
- </div><!-- /.box-header -->
- <div class="box-body">
- <!-- Conversations are loaded here -->
- <div class="direct-chat-messages">
- <!-- Message. Default to the left -->
- <div class="direct-chat-msg">
- <div class="direct-chat-info clearfix">
- <span class="direct-chat-name pull-left">Alexander Pierce</span>
- <span class="direct-chat-timestamp pull-right">23 Jan 2:00 pm</span>
- </div><!-- /.direct-chat-info -->
- <img class="direct-chat-img" src="../dist/img/user1-128x128.jpg" alt="message user image"><!-- /.direct-chat-img -->
- <div class="direct-chat-text">
- Is this template really for free? That's unbelievable!
- </div><!-- /.direct-chat-text -->
- </div><!-- /.direct-chat-msg -->
-
- <!-- Message to the right -->
- <div class="direct-chat-msg right">
- <div class="direct-chat-info clearfix">
- <span class="direct-chat-name pull-right">Sarah Bullock</span>
- <span class="direct-chat-timestamp pull-left">23 Jan 2:05 pm</span>
- </div><!-- /.direct-chat-info -->
- <img class="direct-chat-img" src="../dist/img/user3-128x128.jpg" alt="message user image"><!-- /.direct-chat-img -->
- <div class="direct-chat-text">
- You better believe it!
- </div><!-- /.direct-chat-text -->
- </div><!-- /.direct-chat-msg -->
- </div><!--/.direct-chat-messages-->
-
- <!-- Contacts are loaded here -->
- <div class="direct-chat-contacts">
- <ul class="contacts-list">
- <li>
- <a href="#">
- <img class="contacts-list-img" src="../dist/img/user1-128x128.jpg" alt="Contact Avatar">
- <div class="contacts-list-info">
- <span class="contacts-list-name">
- Count Dracula
- <small class="contacts-list-date pull-right">2/28/2015</small>
- </span>
- <span class="contacts-list-msg">How have you been? I was...</span>
- </div><!-- /.contacts-list-info -->
- </a>
- </li><!-- End Contact Item -->
- </ul><!-- /.contatcts-list -->
- </div><!-- /.direct-chat-pane -->
- </div><!-- /.box-body -->
- <div class="box-footer">
- <div class="input-group">
- <input type="text" name="message" placeholder="Type Message ..." class="form-control">
- <span class="input-group-btn">
- <button type="button" class="btn btn-danger btn-flat">Send</button>
- </span>
- </div>
- </div><!-- /.box-footer-->
- </div><!--/.direct-chat -->
-
-
- Of course you can use direct chat with a solid box by adding the class solid-box
to the box. Here are a couple of examples:
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AdminLTE makes use of the following plugins. For documentation, updates or license information, please visit the provided links.
-
-
-
-
-
-
-
-
- AdminLTE supports the following browsers:
-
- - IE9+
- - Firefox (latest)
- - Safari (latest)
- - Chrome (latest)
- - Opera (latest)
-
- Note: IE9 does not support transitions or animations. The template will function properly but it won't use animations/transitions on IE9.
-
-
-
-
-
-
-
- To upgrade from version 1.x to the lateset version, follow this guide.
- New Files
- Make sure you update all CSS and JS files that are related to AdminLTE. Otherwise, the layout will not
- function properly. Most important files are AdminLTE.css, skins CSS files, and app.js.
- Layout Changes
-
- - The .wrapper div must be placed immediately after the body tag rather than after the header
- - Change the .header div to .main-header
<div class="main-header">
- - Change the .right-side class to .content-wrapper
<div class="content-wrapper">
- - Change the .left-side class to .main-sidebar
<div class="main-sidebar">
- - In the navbar, change .navbar-right to .navbar-custom-menu
<div class="navbar-custom-menu">
-
- Navbar Custom Dropdown Menus
-
- - The icons in the notification menu do not need bg-* classes. They should be replaced with contextual text color class such as text-aqua or text-red.
-
- Login, Registration and Lockscreen Pages
- There are major changes to the HTML markup and style to these pages. The best way is to copy the page's code and customize it.
- And you should be set to go!
- Mailbox
- Mailbox got an upgrade to include three different views. The views are inbox, read mail, and compose new email. To use these views,
- you should use the provided HTML files in the pages/mailbox folder.
- Note: the old mailbox layout has been deprecated in favor of the new one and will be removed by the next release.
-
-
-
-
-
-
-
- Thanks to many of AdminLTE users, there are multiple implementations of the template
- for easy integration with back-end frameworks. The following are some of them:
-
-
-
- Note: these implementations are not supported by Almsaeed Studio. However,
- they do provide a good example of how to integrate AdminLTE into different frameworks. For the latest release
- of AdminLTE, please visit our repository or website
-
-
-
-
-
-
-
- Can AdminLTE be used with Wordpress?
- AdminLTE is an HTML template that can be used for any purpose. However, it is not made to be easily installed on Wordpress. It will require some effort and enough knowledge of the Wordpress script to do so.
-
- Is there an integration guide for PHP frameworks such as Yii or Symfony?
- Short answer, no. However, there are forks and tutorials around the web that provide info on how to integrate with many different frameworks. There are even versions of AdminLTE that are integrated with jQuery ajax, AngularJS and/or MVC5 ASP .NET.
-
- How do I get notified of new AdminLTE versions?
- The best option is to subscribe to our mailing list using the subscription form on Almsaeed Studio.
- If that's not appealing to you, you may watch the repository on Github or visit Almsaeed Studio every now and then for updates and announcements.
-
-
-
-
-
-
-
- AdminLTE
-
- AdminLTE is an open source project that is licensed under the MIT license.
- This allows you to do pretty much anything you want as long as you include
- the copyright in "all copies or substantial portions of the Software."
- Attribution is not required (though very much appreciated).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/style.css b/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/style.css
deleted file mode 100644
index c68a50b..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/documentation/style.css
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Documentation specific stylesheet
- */
-.content-wrapper p {
- padding: 0 10px;
- font-size: 16px;
- position: relative;
- z-index: 30;
-}
-.bring-up {
- position: relative;
- z-index: 30;
-}
-.nth-2-center > tbody > tr > td:last-of-type {
- text-align: center!important;
-}
-.content {
- font-size: 16px;
- z-index: 500;
-}
-
-#components > h3 {
- font-size: 25px;
- color: #000;
-}
-
-#components > h4 {
- font-size: 20px;
- color: #000;
-}
-ul {
- margin-bottom: 20px;
-}
-.page-header {
- /*border-bottom: 1px solid #ddd; */
- margin: 20px 0 10px 0!important;
- position: relative;
- z-index: 1;
- font-size: 30px;
-}
-.page-header span,
-.page-header a {
- z-index: 5;
- display: block;
- background-color: #ecf0f5;
- color: #000;
-}
-.page-header span::before,
-.page-header a::before {
- content: '#';
- font-size: 25px;
- margin-right: 10px;
- color: #3c8dbc;
-}
-.page-header:before,
-#components > h3:before {
- display: block;
- content: " ";
- margin-top: -60px;
- height: 60px;
- visibility: hidden;
- z-index: -10;
-}
-
-.lead {
- font-size: 18px;
- font-weight: 400;
-}
-.eg{
- position: absolute;
- top: 0;
- left: 0;
- display: inline-block;
- background: #d2d6de;
- padding: 5px;
- border-bottom-right-radius: 3px;
- border-top-left-radius: 3px;
- border-bottom: 1px solid #d2d6dc;
- border-right: 1px solid #d2d6dc;
-}
-.eg + * {
- margin-top: 30px;
-}
-.content {
- padding: 10px 25px;
-}
-.hierarchy {
- background: #333;
- color: #fff;
-}
-.plugins-list li {
- width: 50%;
- float: left;
-}
-pre {
- border: none;
-}
-
-.sidebar {
- margin-top: 0;
- padding-top: 0!important;
-}
-.box .main-header {
- z-index: 1000;
- position: relative;
-}
-.treeview .nav li a:hover,
-.treeview .nav li a:active {
- background: transparent;
-}
-p {
- padding: 0!important;
-}
-/* Hemisu Light */
-/* Original theme - http://noahfrederick.com/vim-color-scheme-hemisu/ */
-pre.prettyprint {
- background: white;
- font-family: Menlo, 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', Monaco, Consolas, monospace;
- font-size: 12px;
- line-height: 1.5;
- border: 1px solid #dedede!important;
- padding: 10px;
- max-height: 300px;
- width: auto;
- overflow: auto!important;
-}
-pre.prettyprint > code {
- width: auto;
- overflow: auto!important;
-}
-
-.pln {
- color: #111111;
-}
-
-@media screen {
- .str {
- color: #739200;
- }
-
- .kwd {
- color: #739200;
- }
-
- .com {
- color: #999999;
- }
-
- .typ {
- color: #ff0055;
- }
-
- .lit {
- color: #538192;
- }
-
- .pun {
- color: #111111;
- }
-
- .opn {
- color: #111111;
- }
-
- .clo {
- color: #111111;
- }
-
- .tag {
- color: #111111;
- }
-
- .atn {
- color: #739200;
- }
-
- .atv {
- color: #ff0055;
- }
-
- .dec {
- color: #111111;
- }
-
- .var {
- color: #111111;
- }
-
- .fun {
- color: #538192;
- }
-}
-@media print, projection {
- .str {
- color: #006600;
- }
-
- .kwd {
- color: #006;
- font-weight: bold;
- }
-
- .com {
- color: #600;
- font-style: italic;
- }
-
- .typ {
- color: #404;
- font-weight: bold;
- }
-
- .lit {
- color: #004444;
- }
-
- .pun, .opn, .clo {
- color: #444400;
- }
-
- .tag {
- color: #006;
- font-weight: bold;
- }
-
- .atn {
- color: #440044;
- }
-
- .atv {
- color: #006600;
- }
-}
-/* Specify class=linenums on a pre to get line numbering */
-ol.linenums {
- margin-top: 0;
- margin-bottom: 0;
-}
-
-/* IE indents via margin-left */
-li.L0,
-li.L1,
-li.L2,
-li.L3,
-li.L4,
-li.L5,
-li.L6,
-li.L7,
-li.L8,
-li.L9 {
- /* */
-}
-
-/* Alternate shading for lines */
-li.L1,
-li.L3,
-li.L5,
-li.L7,
-li.L9 {
- /* */
-}
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/buttons.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/buttons.html
deleted file mode 100644
index 3aa572a..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/buttons.html
+++ /dev/null
@@ -1,1713 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Buttons
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Various types of buttons. Using the base class .btn
-
-
- Normal |
- Large .btn-lg |
- Small .btn-sm |
- X-Small .btn-xs |
- Flat .btn-flat |
- Disabled .disabled |
-
-
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Horizontal button groups are easy to create with bootstrap. Just add your buttons
- inside <div class="btn-group"></div>
-
-
-
-
- Button |
- Icons |
- Flat |
- Dropdown |
-
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
- |
-
-
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
- |
-
-
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
- |
-
-
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
- |
-
-
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
- |
-
-
-
-
-
-
-
-
-
-
-
With dropdown
-
-
-
-
Normal
-
-
-
-
Flat
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Normal split buttons:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Flat split buttons:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Mix and match with various background colors. Use base class .btn
and add any available
- .bg-*
class
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Vertical button groups are easy to create with bootstrap. Just add your buttons
- inside <div class="btn-group-vertical"></div>
-
-
-
-
- Button |
- Icons |
- Flat |
- Dropdown |
-
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
- |
-
-
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
- |
-
-
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
- |
-
-
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
- |
-
-
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
-
-
-
-
- |
-
-
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/general.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/general.html
deleted file mode 100644
index e6d6695..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/general.html
+++ /dev/null
@@ -1,1661 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | General UI
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Primary
-
-
-
Disabled
-
#3c8dbc
-
Active
-
-
-
-
-
Info
-
-
-
Disabled
-
#00c0ef
-
Active
-
-
-
-
-
Success
-
-
-
Disabled
-
#00a65a
-
Active
-
-
-
-
-
Warning
-
-
-
Disabled
-
#f39c12
-
Active
-
-
-
-
-
Danger
-
-
-
Disabled
-
#f56954
-
Active
-
-
-
-
-
Gray
-
-
-
Disabled
-
#d2d6de
-
Active
-
-
-
-
-
-
-
-
Navy
-
-
-
Disabled
-
#001F3F
-
Active
-
-
-
-
-
Teal
-
-
-
Disabled
-
#39CCCC
-
Active
-
-
-
-
-
Purple
-
-
-
Disabled
-
#605ca8
-
Active
-
-
-
-
-
Orange
-
-
-
Disabled
-
#ff851b
-
Active
-
-
-
-
-
Maroon
-
-
-
Disabled
-
#D81B60
-
Active
-
-
-
-
-
Black
-
-
-
Disabled
-
#111111
-
Active
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Alert!
- Danger alert preview. This alert is dismissable. A wonderful serenity has taken possession of my entire
- soul, like these sweet mornings of spring which I enjoy with my whole heart.
-
-
-
-
Alert!
- Info alert preview. This alert is dismissable.
-
-
-
-
Alert!
- Warning alert preview. This alert is dismissable.
-
-
-
-
Alert!
- Success alert preview. This alert is dismissable.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
I am a danger callout!
-
-
There is a problem that we need to fix. A wonderful serenity has taken possession of my entire soul,
- like these sweet mornings of spring which I enjoy with my whole heart.
-
-
-
I am an info callout!
-
-
Follow the steps to continue to payment.
-
-
-
I am a warning callout!
-
-
This is a yellow callout.
-
-
-
I am a success callout!
-
-
This is a green callout.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
How to use:
-
-
Exactly like the original bootstrap tabs except you should use
- the custom wrapper .nav-tabs-custom
to achieve this style.
- A wonderful serenity has taken possession of my entire soul,
- like these sweet mornings of spring which I enjoy with my whole heart.
- I am alone, and feel the charm of existence in this spot,
- which was created for the bliss of souls like mine. I am so happy,
- my dear friend, so absorbed in the exquisite sense of mere tranquil existence,
- that I neglect my talents. I should be incapable of drawing a single stroke
- at the present moment; and yet I feel that I never was a greater artist than now.
-
-
-
- The European languages are members of the same family. Their separate existence is a myth.
- For science, music, sport, etc, Europe uses the same vocabulary. The languages only differ
- in their grammar, their pronunciation and their most common words. Everyone realizes why a
- new common language would be desirable: one could refuse to pay expensive translators. To
- achieve this, it would be necessary to have uniform grammar, pronunciation and more common
- words. If several languages coalesce, the grammar of the resulting language is more simple
- and regular than that of the individual languages.
-
-
-
- Lorem Ipsum is simply dummy text of the printing and typesetting industry.
- Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
- when an unknown printer took a galley of type and scrambled it to make a type specimen book.
- It has survived not only five centuries, but also the leap into electronic typesetting,
- remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset
- sheets containing Lorem Ipsum passages, and more recently with desktop publishing software
- like Aldus PageMaker including versions of Lorem Ipsum.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
How to use:
-
-
Exactly like the original bootstrap tabs except you should use
- the custom wrapper .nav-tabs-custom
to achieve this style.
- A wonderful serenity has taken possession of my entire soul,
- like these sweet mornings of spring which I enjoy with my whole heart.
- I am alone, and feel the charm of existence in this spot,
- which was created for the bliss of souls like mine. I am so happy,
- my dear friend, so absorbed in the exquisite sense of mere tranquil existence,
- that I neglect my talents. I should be incapable of drawing a single stroke
- at the present moment; and yet I feel that I never was a greater artist than now.
-
-
-
- The European languages are members of the same family. Their separate existence is a myth.
- For science, music, sport, etc, Europe uses the same vocabulary. The languages only differ
- in their grammar, their pronunciation and their most common words. Everyone realizes why a
- new common language would be desirable: one could refuse to pay expensive translators. To
- achieve this, it would be necessary to have uniform grammar, pronunciation and more common
- words. If several languages coalesce, the grammar of the resulting language is more simple
- and regular than that of the individual languages.
-
-
-
- Lorem Ipsum is simply dummy text of the printing and typesetting industry.
- Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
- when an unknown printer took a galley of type and scrambled it to make a type specimen book.
- It has survived not only five centuries, but also the leap into electronic typesetting,
- remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset
- sheets containing Lorem Ipsum passages, and more recently with desktop publishing software
- like Aldus PageMaker including versions of Lorem Ipsum.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
.progress
-
-
-
- 40% Complete (success)
-
-
-
Class: .sm
-
-
-
Class: .xs
-
-
-
- 60% Complete (warning)
-
-
-
Class: .xxs
-
-
-
- 60% Complete (warning)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 40% Complete (success)
-
-
-
-
-
- 60% Complete (warning)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
By adding the class .vertical
and .progress-sm
, .progress-xs
or
- .progress-xxs
we achieve:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
By adding the class .vertical
we achieve:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3
- wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum
- eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla
- assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred
- nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer
- farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus
- labore sustainable VHS.
-
-
-
-
-
-
-
- Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3
- wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum
- eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla
- assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred
- nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer
- farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus
- labore sustainable VHS.
-
-
-
-
-
-
-
- Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3
- wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum
- eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla
- assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred
- nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer
- farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus
- labore sustainable VHS.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
- First Slide
-
-
-
-

-
-
- Second Slide
-
-
-
-

-
-
- Third Slide
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
h1. Bootstrap heading
-
- h2. Bootstrap heading
-
- h3. Bootstrap heading
- h4. Bootstrap heading
- h5. Bootstrap heading
- h6. Bootstrap heading
-
-
-
-
-
-
-
-
-
-
-
-
Lead to emphasize importance
-
-
Text green to emphasize success
-
-
Text aqua to emphasize info
-
-
Text light blue to emphasize info (2)
-
-
Text red to emphasize danger
-
-
Text yellow to emphasize warning
-
-
Text muted to emphasize general
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.
- Someone famous in Source Title
-
-
-
-
-
-
-
-
-
-
-
-
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.
- Someone famous in Source Title
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - Lorem ipsum dolor sit amet
- - Consectetur adipiscing elit
- - Integer molestie lorem at massa
- - Facilisis in pretium nisl aliquet
- - Nulla volutpat aliquam velit
-
- - Phasellus iaculis neque
- - Purus sodales ultricies
- - Vestibulum laoreet porttitor sem
- - Ac tristique libero volutpat at
-
-
- - Faucibus porta lacus fringilla vel
- - Aenean sit amet erat nunc
- - Eget porttitor lorem
-
-
-
-
-
-
-
-
-
-
-
-
-
- - Lorem ipsum dolor sit amet
- - Consectetur adipiscing elit
- - Integer molestie lorem at massa
- - Facilisis in pretium nisl aliquet
- - Nulla volutpat aliquam velit
-
- - Phasellus iaculis neque
- - Purus sodales ultricies
- - Vestibulum laoreet porttitor sem
- - Ac tristique libero volutpat at
-
-
- - Faucibus porta lacus fringilla vel
- - Aenean sit amet erat nunc
- - Eget porttitor lorem
-
-
-
-
-
-
-
-
-
-
-
-
-
- - Lorem ipsum dolor sit amet
- - Consectetur adipiscing elit
- - Integer molestie lorem at massa
- - Facilisis in pretium nisl aliquet
- - Nulla volutpat aliquam velit
-
- - Phasellus iaculis neque
- - Purus sodales ultricies
- - Vestibulum laoreet porttitor sem
- - Ac tristique libero volutpat at
-
-
- - Faucibus porta lacus fringilla vel
- - Aenean sit amet erat nunc
- - Eget porttitor lorem
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - Description lists
- - A description list is perfect for defining terms.
- - Euismod
- - Vestibulum id ligula porta felis euismod semper eget lacinia odio sem nec elit.
- - Donec id elit non mi porta gravida at eget metus.
- - Malesuada porta
- - Etiam porta sem malesuada magna mollis euismod.
-
-
-
-
-
-
-
-
-
-
-
-
-
- - Description lists
- - A description list is perfect for defining terms.
- - Euismod
- - Vestibulum id ligula porta felis euismod semper eget lacinia odio sem nec elit.
- - Donec id elit non mi porta gravida at eget metus.
- - Malesuada porta
- - Etiam porta sem malesuada magna mollis euismod.
- - Felis euismod semper eget lacinia
- - Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo
- sit amet risus.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/icons.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/icons.html
deleted file mode 100644
index c66881d..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/icons.html
+++ /dev/null
@@ -1,3035 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Icons
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
fa-500px
-
fa-amazon
-
fa-balance-scale
-
fa-battery-0
- (alias)
-
fa-battery-1
- (alias)
-
fa-battery-2
- (alias)
-
fa-battery-3
- (alias)
-
fa-battery-4
- (alias)
-
fa-battery-empty
-
fa-battery-full
-
fa-battery-half
-
fa-battery-quarter
-
- fa-battery-three-quarters
-
-
fa-black-tie
-
fa-calendar-check-o
-
-
fa-calendar-minus-o
-
-
fa-calendar-plus-o
-
fa-calendar-times-o
-
-
fa-cc-diners-club
-
fa-cc-jcb
-
fa-chrome
-
fa-clone
-
fa-commenting
-
fa-commenting-o
-
fa-contao
-
fa-creative-commons
-
-
fa-expeditedssl
-
fa-firefox
-
fa-fonticons
-
fa-genderless
-
fa-get-pocket
-
fa-gg
-
fa-gg-circle
-
fa-hand-grab-o
- (alias)
-
fa-hand-lizard-o
-
fa-hand-paper-o
-
fa-hand-peace-o
-
fa-hand-pointer-o
-
fa-hand-rock-o
-
fa-hand-scissors-o
-
fa-hand-spock-o
-
fa-hand-stop-o
- (alias)
-
fa-hourglass
-
fa-hourglass-1
- (alias)
-
fa-hourglass-2
- (alias)
-
fa-hourglass-3
- (alias)
-
fa-hourglass-end
-
fa-hourglass-half
-
fa-hourglass-o
-
fa-hourglass-start
-
fa-houzz
-
fa-i-cursor
-
fa-industry
-
fa-internet-explorer
-
-
fa-map
-
fa-map-o
-
fa-map-pin
-
fa-map-signs
-
fa-mouse-pointer
-
fa-object-group
-
fa-object-ungroup
-
fa-odnoklassniki
-
- fa-odnoklassniki-square
-
-
fa-opencart
-
fa-opera
-
fa-optin-monster
-
fa-registered
-
fa-safari
-
fa-sticky-note
-
fa-sticky-note-o
-
fa-television
-
fa-trademark
-
fa-tripadvisor
-
fa-tv
- (alias)
-
fa-vimeo
-
fa-wikipedia-w
-
fa-y-combinator
-
fa-yc
- (alias)
-
-
-
-
-
-
-
-
fa-adjust
-
fa-anchor
-
fa-archive
-
fa-area-chart
-
fa-arrows
-
fa-arrows-h
-
fa-arrows-v
-
fa-asterisk
-
fa-at
-
fa-automobile
- (alias)
-
fa-balance-scale
-
fa-ban
-
fa-bank (alias)
-
-
fa-bar-chart
-
fa-bar-chart-o
- (alias)
-
fa-barcode
-
fa-bars
-
fa-battery-0
- (alias)
-
fa-battery-1
- (alias)
-
fa-battery-2
- (alias)
-
fa-battery-3
- (alias)
-
fa-battery-4
- (alias)
-
fa-battery-empty
-
fa-battery-full
-
fa-battery-half
-
fa-battery-quarter
-
- fa-battery-three-quarters
-
-
fa-bed
-
fa-beer
-
fa-bell
-
fa-bell-o
-
fa-bell-slash
-
fa-bell-slash-o
-
fa-bicycle
-
fa-binoculars
-
fa-birthday-cake
-
fa-bolt
-
fa-bomb
-
fa-book
-
fa-bookmark
-
fa-bookmark-o
-
fa-briefcase
-
fa-bug
-
fa-building
-
fa-building-o
-
fa-bullhorn
-
fa-bullseye
-
fa-bus
-
fa-cab (alias)
-
-
fa-calculator
-
fa-calendar
-
fa-calendar-check-o
-
-
fa-calendar-minus-o
-
-
fa-calendar-o
-
fa-calendar-plus-o
-
fa-calendar-times-o
-
-
fa-camera
-
fa-camera-retro
-
fa-car
-
- fa-caret-square-o-down
-
-
- fa-caret-square-o-left
-
-
- fa-caret-square-o-right
-
-
fa-caret-square-o-up
-
-
fa-cart-arrow-down
-
fa-cart-plus
-
fa-cc
-
fa-certificate
-
fa-check
-
fa-check-circle
-
fa-check-circle-o
-
fa-check-square
-
fa-check-square-o
-
fa-child
-
fa-circle
-
fa-circle-o
-
fa-circle-o-notch
-
fa-circle-thin
-
fa-clock-o
-
fa-clone
-
fa-close (alias)
-
-
fa-cloud
-
fa-cloud-download
-
fa-cloud-upload
-
fa-code
-
fa-code-fork
-
fa-coffee
-
fa-cog
-
fa-cogs
-
fa-comment
-
fa-comment-o
-
fa-commenting
-
fa-commenting-o
-
fa-comments
-
fa-comments-o
-
fa-compass
-
fa-copyright
-
fa-creative-commons
-
-
fa-credit-card
-
fa-crop
-
fa-crosshairs
-
fa-cube
-
fa-cubes
-
fa-cutlery
-
fa-dashboard
- (alias)
-
fa-database
-
fa-desktop
-
fa-diamond
-
fa-dot-circle-o
-
fa-download
-
fa-edit (alias)
-
-
fa-ellipsis-h
-
fa-ellipsis-v
-
fa-envelope
-
fa-envelope-o
-
fa-envelope-square
-
fa-eraser
-
fa-exchange
-
fa-exclamation
-
fa-exclamation-circle
-
-
- fa-exclamation-triangle
-
-
fa-external-link
-
- fa-external-link-square
-
-
fa-eye
-
fa-eye-slash
-
fa-eyedropper
-
fa-fax
-
fa-feed (alias)
-
-
fa-female
-
fa-fighter-jet
-
fa-file-archive-o
-
fa-file-audio-o
-
fa-file-code-o
-
fa-file-excel-o
-
fa-file-image-o
-
fa-file-movie-o
- (alias)
-
fa-file-pdf-o
-
fa-file-photo-o
- (alias)
-
fa-file-picture-o
- (alias)
-
fa-file-powerpoint-o
-
-
fa-file-sound-o
- (alias)
-
fa-file-video-o
-
fa-file-word-o
-
fa-file-zip-o
- (alias)
-
fa-film
-
fa-filter
-
fa-fire
-
fa-fire-extinguisher
-
-
fa-flag
-
fa-flag-checkered
-
fa-flag-o
-
fa-flash (alias)
-
-
fa-flask
-
fa-folder
-
fa-folder-o
-
fa-folder-open
-
fa-folder-open-o
-
fa-frown-o
-
fa-futbol-o
-
fa-gamepad
-
fa-gavel
-
fa-gear (alias)
-
-
fa-gears (alias)
-
-
fa-gift
-
fa-glass
-
fa-globe
-
fa-graduation-cap
-
fa-group (alias)
-
-
fa-hand-grab-o
- (alias)
-
fa-hand-lizard-o
-
fa-hand-paper-o
-
fa-hand-peace-o
-
fa-hand-pointer-o
-
fa-hand-rock-o
-
fa-hand-scissors-o
-
fa-hand-spock-o
-
fa-hand-stop-o
- (alias)
-
fa-hdd-o
-
fa-headphones
-
fa-heart
-
fa-heart-o
-
fa-heartbeat
-
fa-history
-
fa-home
-
fa-hotel (alias)
-
-
fa-hourglass
-
fa-hourglass-1
- (alias)
-
fa-hourglass-2
- (alias)
-
fa-hourglass-3
- (alias)
-
fa-hourglass-end
-
fa-hourglass-half
-
fa-hourglass-o
-
fa-hourglass-start
-
fa-i-cursor
-
fa-image (alias)
-
-
fa-inbox
-
fa-industry
-
fa-info
-
fa-info-circle
-
fa-institution
- (alias)
-
fa-key
-
fa-keyboard-o
-
fa-language
-
fa-laptop
-
fa-leaf
-
fa-legal (alias)
-
-
fa-lemon-o
-
fa-level-down
-
fa-level-up
-
fa-life-bouy
- (alias)
-
fa-life-buoy
- (alias)
-
fa-life-ring
-
fa-life-saver
- (alias)
-
fa-lightbulb-o
-
fa-line-chart
-
fa-location-arrow
-
fa-lock
-
fa-magic
-
fa-magnet
-
fa-mail-forward
- (alias)
-
fa-mail-reply
- (alias)
-
fa-mail-reply-all
- (alias)
-
fa-male
-
fa-map
-
fa-map-marker
-
fa-map-o
-
fa-map-pin
-
fa-map-signs
-
fa-meh-o
-
fa-microphone
-
fa-microphone-slash
-
-
fa-minus
-
fa-minus-circle
-
fa-minus-square
-
fa-minus-square-o
-
fa-mobile
-
fa-mobile-phone
- (alias)
-
fa-money
-
fa-moon-o
-
fa-mortar-board
- (alias)
-
fa-motorcycle
-
fa-mouse-pointer
-
fa-music
-
fa-navicon
- (alias)
-
fa-newspaper-o
-
fa-object-group
-
fa-object-ungroup
-
fa-paint-brush
-
fa-paper-plane
-
fa-paper-plane-o
-
fa-paw
-
fa-pencil
-
fa-pencil-square
-
fa-pencil-square-o
-
fa-phone
-
fa-phone-square
-
fa-photo (alias)
-
-
fa-picture-o
-
fa-pie-chart
-
fa-plane
-
fa-plug
-
fa-plus
-
fa-plus-circle
-
fa-plus-square
-
fa-plus-square-o
-
fa-power-off
-
fa-print
-
fa-puzzle-piece
-
fa-qrcode
-
fa-question
-
fa-question-circle
-
fa-quote-left
-
fa-quote-right
-
fa-random
-
fa-recycle
-
fa-refresh
-
fa-registered
-
fa-remove
- (alias)
-
fa-reorder
- (alias)
-
fa-reply
-
fa-reply-all
-
fa-retweet
-
fa-road
-
fa-rocket
-
fa-rss
-
fa-rss-square
-
fa-search
-
fa-search-minus
-
fa-search-plus
-
fa-send (alias)
-
-
fa-send-o
- (alias)
-
fa-server
-
fa-share
-
fa-share-alt
-
fa-share-alt-square
-
-
fa-share-square
-
fa-share-square-o
-
fa-shield
-
fa-ship
-
fa-shopping-cart
-
fa-sign-in
-
fa-sign-out
-
fa-signal
-
fa-sitemap
-
fa-sliders
-
fa-smile-o
-
fa-soccer-ball-o
- (alias)
-
fa-sort
-
fa-sort-alpha-asc
-
fa-sort-alpha-desc
-
fa-sort-amount-asc
-
fa-sort-amount-desc
-
-
fa-sort-asc
-
fa-sort-desc
-
fa-sort-down
- (alias)
-
fa-sort-numeric-asc
-
-
fa-sort-numeric-desc
-
-
fa-sort-up
- (alias)
-
fa-space-shuttle
-
fa-spinner
-
fa-spoon
-
fa-square
-
fa-square-o
-
fa-star
-
fa-star-half
-
fa-star-half-empty
- (alias)
-
fa-star-half-full
- (alias)
-
fa-star-half-o
-
fa-star-o
-
fa-sticky-note
-
fa-sticky-note-o
-
fa-street-view
-
fa-suitcase
-
fa-sun-o
-
fa-support
- (alias)
-
fa-tablet
-
fa-tachometer
-
fa-tag
-
fa-tags
-
fa-tasks
-
fa-taxi
-
fa-television
-
fa-terminal
-
fa-thumb-tack
-
fa-thumbs-down
-
fa-thumbs-o-down
-
fa-thumbs-o-up
-
fa-thumbs-up
-
fa-ticket
-
fa-times
-
fa-times-circle
-
fa-times-circle-o
-
fa-tint
-
fa-toggle-down
- (alias)
-
fa-toggle-left
- (alias)
-
fa-toggle-off
-
fa-toggle-on
-
fa-toggle-right
- (alias)
-
fa-toggle-up
- (alias)
-
fa-trademark
-
fa-trash
-
fa-trash-o
-
fa-tree
-
fa-trophy
-
fa-truck
-
fa-tty
-
fa-tv
- (alias)
-
fa-umbrella
-
fa-university
-
fa-unlock
-
fa-unlock-alt
-
fa-unsorted
- (alias)
-
fa-upload
-
fa-user
-
fa-user-plus
-
fa-user-secret
-
fa-user-times
-
fa-users
-
fa-video-camera
-
fa-volume-down
-
fa-volume-off
-
fa-volume-up
-
fa-warning
- (alias)
-
fa-wheelchair
-
fa-wifi
-
fa-wrench
-
-
-
-
-
-
-
-
fa-hand-grab-o
- (alias)
-
fa-hand-lizard-o
-
fa-hand-o-down
-
fa-hand-o-left
-
fa-hand-o-right
-
fa-hand-o-up
-
fa-hand-paper-o
-
fa-hand-peace-o
-
fa-hand-pointer-o
-
fa-hand-rock-o
-
fa-hand-scissors-o
-
fa-hand-spock-o
-
fa-hand-stop-o
- (alias)
-
fa-thumbs-down
-
fa-thumbs-o-down
-
fa-thumbs-o-up
-
fa-thumbs-up
-
-
-
-
-
-
-
-
fa-ambulance
-
fa-automobile
- (alias)
-
fa-bicycle
-
fa-bus
-
fa-cab (alias)
-
-
fa-car
-
fa-fighter-jet
-
fa-motorcycle
-
fa-plane
-
fa-rocket
-
fa-ship
-
fa-space-shuttle
-
fa-subway
-
fa-taxi
-
fa-train
-
fa-truck
-
fa-wheelchair
-
-
-
-
-
-
-
-
fa-genderless
-
fa-intersex
- (alias)
-
fa-mars
-
fa-mars-double
-
fa-mars-stroke
-
fa-mars-stroke-h
-
fa-mars-stroke-v
-
fa-mercury
-
fa-neuter
-
fa-transgender
-
fa-transgender-alt
-
fa-venus
-
fa-venus-double
-
fa-venus-mars
-
-
-
-
-
-
-
-
fa-file
-
fa-file-archive-o
-
fa-file-audio-o
-
fa-file-code-o
-
fa-file-excel-o
-
fa-file-image-o
-
fa-file-movie-o
- (alias)
-
fa-file-o
-
fa-file-pdf-o
-
fa-file-photo-o
- (alias)
-
fa-file-picture-o
- (alias)
-
fa-file-powerpoint-o
-
-
fa-file-sound-o
- (alias)
-
fa-file-text
-
fa-file-text-o
-
fa-file-video-o
-
fa-file-word-o
-
fa-file-zip-o
- (alias)
-
-
-
-
-
-
-
-
fa-circle-o-notch
-
fa-cog
-
fa-gear (alias)
-
-
fa-refresh
-
fa-spinner
-
-
-
-
-
-
-
-
-
-
fa-cc-amex
-
fa-cc-diners-club
-
fa-cc-discover
-
fa-cc-jcb
-
fa-cc-mastercard
-
fa-cc-paypal
-
fa-cc-stripe
-
fa-cc-visa
-
fa-credit-card
-
fa-google-wallet
-
fa-paypal
-
-
-
-
-
-
-
-
fa-area-chart
-
fa-bar-chart
-
fa-bar-chart-o
- (alias)
-
fa-line-chart
-
fa-pie-chart
-
-
-
-
-
-
-
-
fa-bitcoin
- (alias)
-
fa-btc
-
fa-cny (alias)
-
-
fa-dollar
- (alias)
-
fa-eur
-
fa-euro (alias)
-
-
fa-gbp
-
fa-gg
-
fa-gg-circle
-
fa-ils
-
fa-inr
-
fa-jpy
-
fa-krw
-
fa-money
-
fa-rmb (alias)
-
-
fa-rouble
- (alias)
-
fa-rub
-
fa-ruble (alias)
-
-
fa-rupee (alias)
-
-
fa-shekel
- (alias)
-
fa-sheqel
- (alias)
-
fa-try
-
fa-turkish-lira
- (alias)
-
fa-usd
-
fa-won (alias)
-
-
fa-yen (alias)
-
-
-
-
-
-
-
-
-
fa-align-center
-
fa-align-justify
-
fa-align-left
-
fa-align-right
-
fa-bold
-
fa-chain (alias)
-
-
fa-chain-broken
-
fa-clipboard
-
fa-columns
-
fa-copy (alias)
-
-
fa-cut (alias)
-
-
fa-dedent
- (alias)
-
fa-eraser
-
fa-file
-
fa-file-o
-
fa-file-text
-
fa-file-text-o
-
fa-files-o
-
fa-floppy-o
-
fa-font
-
fa-header
-
fa-indent
-
fa-italic
-
fa-link
-
fa-list
-
fa-list-alt
-
fa-list-ol
-
fa-list-ul
-
fa-outdent
-
fa-paperclip
-
fa-paragraph
-
fa-paste (alias)
-
-
fa-repeat
-
fa-rotate-left
- (alias)
-
fa-rotate-right
- (alias)
-
fa-save (alias)
-
-
fa-scissors
-
fa-strikethrough
-
fa-subscript
-
fa-superscript
-
fa-table
-
fa-text-height
-
fa-text-width
-
fa-th
-
fa-th-large
-
fa-th-list
-
fa-underline
-
fa-undo
-
fa-unlink
- (alias)
-
-
-
-
-
-
-
-
fa-angle-double-down
-
-
fa-angle-double-left
-
-
fa-angle-double-right
-
-
fa-angle-double-up
-
fa-angle-down
-
fa-angle-left
-
fa-angle-right
-
fa-angle-up
-
fa-arrow-circle-down
-
-
fa-arrow-circle-left
-
-
- fa-arrow-circle-o-down
-
-
- fa-arrow-circle-o-left
-
-
- fa-arrow-circle-o-right
-
-
fa-arrow-circle-o-up
-
-
fa-arrow-circle-right
-
-
fa-arrow-circle-up
-
fa-arrow-down
-
fa-arrow-left
-
fa-arrow-right
-
fa-arrow-up
-
fa-arrows
-
fa-arrows-alt
-
fa-arrows-h
-
fa-arrows-v
-
fa-caret-down
-
fa-caret-left
-
fa-caret-right
-
- fa-caret-square-o-down
-
-
- fa-caret-square-o-left
-
-
- fa-caret-square-o-right
-
-
fa-caret-square-o-up
-
-
fa-caret-up
-
- fa-chevron-circle-down
-
-
- fa-chevron-circle-left
-
-
- fa-chevron-circle-right
-
-
fa-chevron-circle-up
-
-
fa-chevron-down
-
fa-chevron-left
-
fa-chevron-right
-
fa-chevron-up
-
fa-exchange
-
fa-hand-o-down
-
fa-hand-o-left
-
fa-hand-o-right
-
fa-hand-o-up
-
fa-long-arrow-down
-
fa-long-arrow-left
-
fa-long-arrow-right
-
-
fa-long-arrow-up
-
fa-toggle-down
- (alias)
-
fa-toggle-left
- (alias)
-
fa-toggle-right
- (alias)
-
fa-toggle-up
- (alias)
-
-
-
-
-
-
-
-
fa-arrows-alt
-
fa-backward
-
fa-compress
-
fa-eject
-
fa-expand
-
fa-fast-backward
-
fa-fast-forward
-
fa-forward
-
fa-pause
-
fa-play
-
fa-play-circle
-
fa-play-circle-o
-
fa-random
-
fa-step-backward
-
fa-step-forward
-
fa-stop
-
fa-youtube-play
-
-
-
-
-
-
-
-
- - All brand icons are trademarks of their respective owners.
- - The use of these trademarks does not indicate endorsement of the trademark holder by Font
- Awesome, nor vice versa.
-
-
-
-
-
fa-500px
-
fa-adn
-
fa-amazon
-
fa-android
-
fa-angellist
-
fa-apple
-
fa-behance
-
fa-behance-square
-
fa-bitbucket
-
fa-bitbucket-square
-
-
fa-bitcoin
- (alias)
-
fa-black-tie
-
fa-btc
-
fa-buysellads
-
fa-cc-amex
-
fa-cc-diners-club
-
fa-cc-discover
-
fa-cc-jcb
-
fa-cc-mastercard
-
fa-cc-paypal
-
fa-cc-stripe
-
fa-cc-visa
-
fa-chrome
-
fa-codepen
-
fa-connectdevelop
-
fa-contao
-
fa-css3
-
fa-dashcube
-
fa-delicious
-
fa-deviantart
-
fa-digg
-
fa-dribbble
-
fa-dropbox
-
fa-drupal
-
fa-empire
-
fa-expeditedssl
-
fa-facebook
-
fa-facebook-f
- (alias)
-
fa-facebook-official
-
-
fa-facebook-square
-
fa-firefox
-
fa-flickr
-
fa-fonticons
-
fa-forumbee
-
fa-foursquare
-
fa-ge
- (alias)
-
fa-get-pocket
-
fa-gg
-
fa-gg-circle
-
fa-git
-
fa-git-square
-
fa-github
-
fa-github-alt
-
fa-github-square
-
fa-gittip
- (alias)
-
fa-google
-
fa-google-plus
-
fa-google-plus-square
-
-
fa-google-wallet
-
fa-gratipay
-
fa-hacker-news
-
fa-houzz
-
fa-html5
-
fa-instagram
-
fa-internet-explorer
-
-
fa-ioxhost
-
fa-joomla
-
fa-jsfiddle
-
fa-lastfm
-
fa-lastfm-square
-
fa-leanpub
-
fa-linkedin
-
fa-linkedin-square
-
fa-linux
-
fa-maxcdn
-
fa-meanpath
-
fa-medium
-
fa-odnoklassniki
-
- fa-odnoklassniki-square
-
-
fa-opencart
-
fa-openid
-
fa-opera
-
fa-optin-monster
-
fa-pagelines
-
fa-paypal
-
fa-pied-piper
-
fa-pied-piper-alt
-
fa-pinterest
-
fa-pinterest-p
-
fa-pinterest-square
-
-
fa-qq
-
fa-ra
- (alias)
-
fa-rebel
-
fa-reddit
-
fa-reddit-square
-
fa-renren
-
fa-safari
-
fa-sellsy
-
fa-share-alt
-
fa-share-alt-square
-
-
fa-shirtsinbulk
-
fa-simplybuilt
-
fa-skyatlas
-
fa-skype
-
fa-slack
-
fa-slideshare
-
fa-soundcloud
-
fa-spotify
-
fa-stack-exchange
-
fa-stack-overflow
-
fa-steam
-
fa-steam-square
-
fa-stumbleupon
-
fa-stumbleupon-circle
-
-
fa-tencent-weibo
-
fa-trello
-
fa-tripadvisor
-
fa-tumblr
-
fa-tumblr-square
-
fa-twitch
-
fa-twitter
-
fa-twitter-square
-
fa-viacoin
-
fa-vimeo
-
fa-vimeo-square
-
fa-vine
-
fa-vk
-
fa-wechat
- (alias)
-
fa-weibo
-
fa-weixin
-
fa-whatsapp
-
fa-wikipedia-w
-
fa-windows
-
fa-wordpress
-
fa-xing
-
fa-xing-square
-
fa-y-combinator
-
- fa-y-combinator-square (alias)
-
fa-yahoo
-
fa-yc
- (alias)
-
fa-yc-square
- (alias)
-
fa-yelp
-
fa-youtube
-
fa-youtube-play
-
fa-youtube-square
-
-
-
-
-
-
-
-
fa-ambulance
-
fa-h-square
-
fa-heart
-
fa-heart-o
-
fa-heartbeat
-
fa-hospital-o
-
fa-medkit
-
fa-plus-square
-
fa-stethoscope
-
fa-user-md
-
fa-wheelchair
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/modals.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/modals.html
deleted file mode 100644
index faa87ec..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/modals.html
+++ /dev/null
@@ -1,911 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Modals
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/sliders.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/sliders.html
deleted file mode 100644
index a7265b8..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/sliders.html
+++ /dev/null
@@ -1,821 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | UI Sliders
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/timeline.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/timeline.html
deleted file mode 100644
index a669da6..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/UI/timeline.html
+++ /dev/null
@@ -1,913 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Timeline
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
- 10 Feb. 2014
-
-
-
-
- -
-
-
-
-
12:05
-
-
-
-
- Etsy doostang zoodles disqus groupon greplin oooj voxy zoodles,
- weebly ning heekya handango imeem plugg dopplr jibjab, movity
- jajah plickers sifteo edmodo ifttt zimbra. Babblely odeo kaboodle
- quora plaxo ideeli hulu weebly balihoo...
-
-
-
-
-
-
- -
-
-
-
- 5 mins ago
-
-
-
-
-
-
- -
-
-
-
-
27 mins ago
-
-
-
-
- Take me to your leader!
- Switzerland is small and neutral!
- We are more like Germany, ambitious and misunderstood!
-
-
-
-
-
-
- -
-
- 3 Jan. 2014
-
-
-
-
- -
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<ul class="timeline">
-
- <!-- timeline time label -->
- <li class="time-label">
- <span class="bg-red">
- 10 Feb. 2014
- </span>
- </li>
- <!-- /.timeline-label -->
-
- <!-- timeline item -->
- <li>
- <!-- timeline icon -->
- <i class="fa fa-envelope bg-blue"></i>
- <div class="timeline-item">
- <span class="time"><i class="fa fa-clock-o"></i> 12:05</span>
-
- <h3 class="timeline-header"><a href="#">Support Team</a> ...</h3>
-
- <div class="timeline-body">
- ...
- Content goes here
- </div>
-
- <div class="timeline-footer">
- <a class="btn btn-primary btn-xs">...</a>
- </div>
- </div>
- </li>
- <!-- END timeline item -->
-
- ...
-
-</ul>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/calendar.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/calendar.html
deleted file mode 100644
index fe09416..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/calendar.html
+++ /dev/null
@@ -1,983 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Calendar
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Lunch
-
Go home
-
Do homework
-
Work on UI design
-
Sleep tight
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/charts/chartjs.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/charts/chartjs.html
deleted file mode 100644
index ade25b8..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/charts/chartjs.html
+++ /dev/null
@@ -1,922 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | ChartJS
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/charts/flot.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/charts/flot.html
deleted file mode 100644
index 68398c6..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/charts/flot.html
+++ /dev/null
@@ -1,1132 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Flot Charts
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/charts/inline.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/charts/inline.html
deleted file mode 100644
index f3dfd8d..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/charts/inline.html
+++ /dev/null
@@ -1,1306 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Inline Charts
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
data-thickness="0.1"
-
-
-
-
-
-
data-angleArc="250"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
data-thickness="0.1"
-
-
-
-
-
-
data-angleArc="250"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
The following was created using data tags
-
-
The following three inline (sparkline) chart have been initialized to read and interpret data tags
-
-
-
-
-
-
-
-
-
-
-
-
-
- 6,4,7,8,4,3,2,2,5,6,7,4,1,5,7,9,9,8,7,6
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 6,4,8, 9, 10, 5, 13, 18, 21, 7, 9
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Mouse speed Loading..
-
-
-
- Inline 10,8,9,3,5,8,5
- line graphs
- 8,4,0,0,0,0,1,4,4,10,10,10,10,0,0,0,4,6,5,9,10
-
-
-
- Bar charts 10,8,9,3,5,8,5
- negative values: -3,1,2,0,3,-1
- stacked: 0:2,2:4,4:2,4:1
-
-
-
- Composite inline
- 8,4,0,0,0,0,1,4,4,10,10,10,10,0,0,0,4,6,5,9,10
-
-
-
- Inline with normal range
- 8,4,0,0,0,0,1,4,4,10,10,10,10,0,0,0,4,6,5,9,10
-
-
-
- Composite bar
- 4,6,7,7,4,3,2,1,4
-
-
-
- Discrete
- 4,6,7,7,4,3,2,1,4,4,5,6,7,6,6,2,4,5
-
- Discrete with threshold
- 4,6,7,7,4,3,2,1,4
-
-
-
- Bullet charts
- 10,12,12,9,7
- 14,12,12,9,7
- 10,12,14,9,7
-
-
-
-
-
- Customize size and colours
- 10,8,9,3,5,8,5,7
-
-
-
- Tristate charts
- 1,1,0,1,-1,-1,1,-1,0,0,1,1
- (think games won, lost or drawn)
-
-
-
- Tristate chart using a colour map:
- 1,2,0,2,-1,-2,1,-2,0,0,1,1
-
-
-
- Box Plot: 4,27,34,52,54,59,61,68,78,82,85,87,91,93,100
- Pre-computed box plot Loading..
-
-
-
- Pie charts
- 1,1,2
- 1,5
- 20,50,80
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/charts/morris.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/charts/morris.html
deleted file mode 100644
index 0bcae19..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/charts/morris.html
+++ /dev/null
@@ -1,911 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Morris.js Charts
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Warning!
-
-
Morris.js charts are no longer maintained by its author. We would recommend using any of the other
- charts that come with the template.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/404.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/404.html
deleted file mode 100644
index 7ea2c12..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/404.html
+++ /dev/null
@@ -1,759 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | 404 Page not found
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
404
-
-
-
Oops! Page not found.
-
-
- We could not find the page you were looking for.
- Meanwhile, you may return to dashboard or try using the search form.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/500.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/500.html
deleted file mode 100644
index 620f95d..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/500.html
+++ /dev/null
@@ -1,760 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | 500 Error
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
500
-
-
-
Oops! Something went wrong.
-
-
- We will work on fixing that right away.
- Meanwhile, you may return to dashboard or try using the search form.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/blank.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/blank.html
deleted file mode 100644
index 700b53e..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/blank.html
+++ /dev/null
@@ -1,664 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Blank Page
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Start creating your amazing application!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/invoice-print.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/invoice-print.html
deleted file mode 100644
index ee095c8..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/invoice-print.html
+++ /dev/null
@@ -1,173 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Invoice
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- From
-
- Admin, Inc.
- 795 Folsom Ave, Suite 600
- San Francisco, CA 94107
- Phone: (804) 123-5432
- Email: info@almasaeedstudio.com
-
-
-
-
- To
-
- John Doe
- 795 Folsom Ave, Suite 600
- San Francisco, CA 94107
- Phone: (555) 539-1037
- Email: john.doe@example.com
-
-
-
-
- Invoice #007612
-
- Order ID: 4F3S8J
- Payment Due: 2/22/2014
- Account: 968-34567
-
-
-
-
-
-
-
-
-
-
-
- Qty |
- Product |
- Serial # |
- Description |
- Subtotal |
-
-
-
-
- 1 |
- Call of Duty |
- 455-981-221 |
- El snort testosterone trophy driving gloves handsome |
- $64.50 |
-
-
- 1 |
- Need for Speed IV |
- 247-925-726 |
- Wes Anderson umami biodiesel |
- $50.00 |
-
-
- 1 |
- Monsters DVD |
- 735-845-642 |
- Terry Richardson helvetica tousled street art master |
- $10.70 |
-
-
- 1 |
- Grown Ups Blue Ray |
- 422-568-642 |
- Tousled lomo letterpress |
- $25.99 |
-
-
-
-
-
-
-
-
-
-
-
-
Payment Methods:
-

-

-

-

-
-
- Etsy doostang zoodles disqus groupon greplin oooj voxy zoodles, weebly ning heekya handango imeem plugg dopplr
- jibjab, movity jajah plickers sifteo edmodo ifttt zimbra.
-
-
-
-
-
Amount Due 2/22/2014
-
-
-
-
- Subtotal: |
- $250.30 |
-
-
- Tax (9.3%) |
- $10.34 |
-
-
- Shipping: |
- $5.80 |
-
-
- Total: |
- $265.24 |
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/invoice.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/invoice.html
deleted file mode 100644
index 8b04410..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/invoice.html
+++ /dev/null
@@ -1,889 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Invoice
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Note:
- This page has been enhanced for printing. Click the print button at the bottom of the invoice to test.
-
-
-
-
-
-
-
-
-
-
- From
-
- Admin, Inc.
- 795 Folsom Ave, Suite 600
- San Francisco, CA 94107
- Phone: (804) 123-5432
- Email: info@almasaeedstudio.com
-
-
-
-
- To
-
- John Doe
- 795 Folsom Ave, Suite 600
- San Francisco, CA 94107
- Phone: (555) 539-1037
- Email: john.doe@example.com
-
-
-
-
- Invoice #007612
-
- Order ID: 4F3S8J
- Payment Due: 2/22/2014
- Account: 968-34567
-
-
-
-
-
-
-
-
-
-
-
- Qty |
- Product |
- Serial # |
- Description |
- Subtotal |
-
-
-
-
- 1 |
- Call of Duty |
- 455-981-221 |
- El snort testosterone trophy driving gloves handsome |
- $64.50 |
-
-
- 1 |
- Need for Speed IV |
- 247-925-726 |
- Wes Anderson umami biodiesel |
- $50.00 |
-
-
- 1 |
- Monsters DVD |
- 735-845-642 |
- Terry Richardson helvetica tousled street art master |
- $10.70 |
-
-
- 1 |
- Grown Ups Blue Ray |
- 422-568-642 |
- Tousled lomo letterpress |
- $25.99 |
-
-
-
-
-
-
-
-
-
-
-
-
Payment Methods:
-

-

-

-

-
-
- Etsy doostang zoodles disqus groupon greplin oooj voxy zoodles, weebly ning heekya handango imeem plugg
- dopplr jibjab, movity jajah plickers sifteo edmodo ifttt zimbra.
-
-
-
-
-
Amount Due 2/22/2014
-
-
-
-
- Subtotal: |
- $250.30 |
-
-
- Tax (9.3%) |
- $10.34 |
-
-
- Shipping: |
- $5.80 |
-
-
- Total: |
- $265.24 |
-
-
-
-
-
-
-
-
-
-
-
-
Print
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/lockscreen.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/lockscreen.html
deleted file mode 100644
index a7f7424..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/lockscreen.html
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Lockscreen
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
John Doe
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
- Enter your password to retrieve your session
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/login.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/login.html
deleted file mode 100644
index 1e47e84..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/login.html
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Log in
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/pace.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/pace.html
deleted file mode 100644
index 0f2eaf8..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/pace.html
+++ /dev/null
@@ -1,689 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Pace Page
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Pace loading works automatically on page. You can still implement it with ajax requests by adding this js:
-
$(document).ajaxStart(function() { Pace.restart(); });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/profile.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/profile.html
deleted file mode 100644
index af61d0a..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/profile.html
+++ /dev/null
@@ -1,1088 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | User Profile
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
Nina Mcintire
-
-
Software Engineer
-
-
-
-
Follow
-
-
-
-
-
-
-
-
-
-
-
Education
-
-
- B.S. in Computer Science from the University of Tennessee at Knoxville
-
-
-
-
-
Location
-
-
Malibu, California
-
-
-
-
Skills
-
-
- UI Design
- Coding
- Javascript
- PHP
- Node.js
-
-
-
-
-
Notes
-
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam fermentum enim neque.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Lorem ipsum represents a long-held tradition for designers,
- typographers and the like. Some people hate it and argue for
- its demise, but others ignore the hate as they create awesome
- tools to help create filler text for everyone from bacon lovers
- to Charlie Sheen fans.
-
-
-
-
-
-
-
-
-
-
-

-
- Sarah Ross
-
-
-
Sent you a message - 3 days ago
-
-
-
- Lorem ipsum represents a long-held tradition for designers,
- typographers and the like. Some people hate it and argue for
- its demise, but others ignore the hate as they create awesome
- tools to help create filler text for everyone from bacon lovers
- to Charlie Sheen fans.
-
-
-
-
-
-
-
-
-
-

-
- Adam Jones
-
-
-
Posted 5 photos - 5 days ago
-
-
-
-
-

-
-
-
-
-
-

-
-

-
-
-
-

-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
- 10 Feb. 2014
-
-
-
-
- -
-
-
-
-
12:05
-
-
-
-
- Etsy doostang zoodles disqus groupon greplin oooj voxy zoodles,
- weebly ning heekya handango imeem plugg dopplr jibjab, movity
- jajah plickers sifteo edmodo ifttt zimbra. Babblely odeo kaboodle
- quora plaxo ideeli hulu weebly balihoo...
-
-
-
-
-
-
- -
-
-
-
- 5 mins ago
-
-
-
-
-
-
- -
-
-
-
-
27 mins ago
-
-
-
-
- Take me to your leader!
- Switzerland is small and neutral!
- We are more like Germany, ambitious and misunderstood!
-
-
-
-
-
-
- -
-
- 3 Jan. 2014
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/register.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/register.html
deleted file mode 100644
index 29d8ccf..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/examples/register.html
+++ /dev/null
@@ -1,102 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Registration Page
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/forms/advanced.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/forms/advanced.html
deleted file mode 100644
index dc7f8d5..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/forms/advanced.html
+++ /dev/null
@@ -1,1230 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Advanced form elements
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/forms/editors.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/forms/editors.html
deleted file mode 100644
index bedf07b..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/forms/editors.html
+++ /dev/null
@@ -1,811 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Editors
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/forms/general.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/forms/general.html
deleted file mode 100644
index 4ff53b5..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/forms/general.html
+++ /dev/null
@@ -1,1119 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | General Form Elements
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- @
-
-
-
-
-
-
- .00
-
-
-
-
- $
-
- .00
-
-
-
With icons
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
With checkbox and radio inputs
-
-
-
-
-
With buttons
-
-
Large: .input-group.input-group-lg
-
-
-
-
Normal
-
-
-
-
Small .input-group.input-group-sm
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/layout/boxed.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/layout/boxed.html
deleted file mode 100644
index d02e250..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/layout/boxed.html
+++ /dev/null
@@ -1,657 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Boxed Layout
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Tip!
-
-
Add the layout-boxed class to the body tag to get this layout. The boxed layout is helpful when working on
- large screens because it prevents the site from stretching very wide.
-
-
-
-
-
- Start creating your amazing application!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/layout/collapsed-sidebar.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/layout/collapsed-sidebar.html
deleted file mode 100644
index aa68c7a..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/layout/collapsed-sidebar.html
+++ /dev/null
@@ -1,663 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Collapsed Sidebar Layout
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Tip!
-
-
Add the sidebar-collapse class to the body tag to get this layout. You should combine this option with a
- fixed layout if you have a long sidebar. Doing that will prevent your page content from getting stretched
- vertically.
-
-
-
-
-
- Start creating your amazing application!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/layout/fixed.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/layout/fixed.html
deleted file mode 100644
index ad8ff0d..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/layout/fixed.html
+++ /dev/null
@@ -1,663 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Fixed Layout
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Tip!
-
-
Add the fixed class to the body tag to get this layout. The fixed layout is your best option if your sidebar
- is bigger than your content because it prevents extra unwanted scrolling.
-
-
-
-
-
- Start creating your amazing application!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/layout/top-nav.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/layout/top-nav.html
deleted file mode 100644
index d933173..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/layout/top-nav.html
+++ /dev/null
@@ -1,293 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Top Navigation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Tip!
-
-
Add the layout-top-nav class to the body tag to get this layout. This feature can also be used with a
- sidebar! So use this class if you want to remove the custom dropdown menus from the navbar and use regular
- links instead.
-
-
-
Warning!
-
-
The construction of this layout differs from the normal one. In other words, the HTML markup of the navbar
- and the content will slightly differ than that of the normal layout.
-
-
-
-
- The great content goes here
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/mailbox/compose.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/mailbox/compose.html
deleted file mode 100644
index f0a787d..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/mailbox/compose.html
+++ /dev/null
@@ -1,760 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Compose Message
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/mailbox/mailbox.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/mailbox/mailbox.html
deleted file mode 100644
index 8f5dbbd..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/mailbox/mailbox.html
+++ /dev/null
@@ -1,940 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Mailbox
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/mailbox/read-mail.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/mailbox/read-mail.html
deleted file mode 100644
index 6593780..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/mailbox/read-mail.html
+++ /dev/null
@@ -1,815 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Read Mail
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Message Subject Is Placed Here
- From: help@example.com
- 15 Feb. 2016 11:03 PM
-
-
-
-
-
-
Hello John,
-
-
Keffiyeh blog actually fashion axe vegan, irony biodiesel. Cold-pressed hoodie chillwave put a bird
- on it aesthetic, bitters brunch meggings vegan iPhone. Dreamcatcher vegan scenester mlkshk. Ethical
- master cleanse Bushwick, occupy Thundercats banjo cliche ennui farm-to-table mlkshk fanny pack
- gluten-free. Marfa butcher vegan quinoa, bicycle rights disrupt tofu scenester chillwave 3 wolf moon
- asymmetrical taxidermy pour-over. Quinoa tote bag fashion axe, Godard disrupt migas church-key tofu
- blog locavore. Thundercats cronut polaroid Neutra tousled, meh food truck selfies narwhal American
- Apparel.
-
-
Raw denim McSweeney's bicycle rights, iPhone trust fund quinoa Neutra VHS kale chips vegan PBR&B
- literally Thundercats +1. Forage tilde four dollar toast, banjo health goth paleo butcher. Four dollar
- toast Brooklyn pour-over American Apparel sustainable, lumbersexual listicle gluten-free health goth
- umami hoodie. Synth Echo Park bicycle rights DIY farm-to-table, retro kogi sriracha dreamcatcher PBR&B
- flannel hashtag irony Wes Anderson. Lumbersexual Williamsburg Helvetica next level. Cold-pressed
- slow-carb pop-up normcore Thundercats Portland, cardigan literally meditation lumbersexual crucifix.
- Wayfarers raw denim paleo Bushwick, keytar Helvetica scenester keffiyeh 8-bit irony mumblecore
- whatever viral Truffaut.
-
-
Post-ironic shabby chic VHS, Marfa keytar flannel lomo try-hard keffiyeh cray. Actually fap fanny
- pack yr artisan trust fund. High Life dreamcatcher church-key gentrify. Tumblr stumptown four dollar
- toast vinyl, cold-pressed try-hard blog authentic keffiyeh Helvetica lo-fi tilde Intelligentsia. Lomo
- locavore salvia bespoke, twee fixie paleo cliche brunch Schlitz blog McSweeney's messenger bag swag
- slow-carb. Odd Future photo booth pork belly, you probably haven't heard of them actually tofu ennui
- keffiyeh lo-fi Truffaut health goth. Narwhal sustainable retro disrupt.
-
-
Skateboard artisan letterpress before they sold out High Life messenger bag. Bitters chambray
- leggings listicle, drinking vinegar chillwave synth. Fanny pack hoodie American Apparel twee. American
- Apparel PBR listicle, salvia aesthetic occupy sustainable Neutra kogi. Organic synth Tumblr viral
- plaid, shabby chic single-origin coffee Etsy 3 wolf moon slow-carb Schlitz roof party tousled squid
- vinyl. Readymade next level literally trust fund. Distillery master cleanse migas, Vice sriracha
- flannel chambray chia cronut.
-
-
Thanks,
Jane
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/tables/data.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/tables/data.html
deleted file mode 100644
index 6ca57c4..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/tables/data.html
+++ /dev/null
@@ -1,1646 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Data Tables
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Rendering engine |
- Browser |
- Platform(s) |
- Engine version |
- CSS grade |
-
-
-
-
- Trident |
- Internet
- Explorer 4.0
- |
- Win 95+ |
- 4 |
- X |
-
-
- Trident |
- Internet
- Explorer 5.0
- |
- Win 95+ |
- 5 |
- C |
-
-
- Trident |
- Internet
- Explorer 5.5
- |
- Win 95+ |
- 5.5 |
- A |
-
-
- Trident |
- Internet
- Explorer 6
- |
- Win 98+ |
- 6 |
- A |
-
-
- Trident |
- Internet Explorer 7 |
- Win XP SP2+ |
- 7 |
- A |
-
-
- Trident |
- AOL browser (AOL desktop) |
- Win XP |
- 6 |
- A |
-
-
- Gecko |
- Firefox 1.0 |
- Win 98+ / OSX.2+ |
- 1.7 |
- A |
-
-
- Gecko |
- Firefox 1.5 |
- Win 98+ / OSX.2+ |
- 1.8 |
- A |
-
-
- Gecko |
- Firefox 2.0 |
- Win 98+ / OSX.2+ |
- 1.8 |
- A |
-
-
- Gecko |
- Firefox 3.0 |
- Win 2k+ / OSX.3+ |
- 1.9 |
- A |
-
-
- Gecko |
- Camino 1.0 |
- OSX.2+ |
- 1.8 |
- A |
-
-
- Gecko |
- Camino 1.5 |
- OSX.3+ |
- 1.8 |
- A |
-
-
- Gecko |
- Netscape 7.2 |
- Win 95+ / Mac OS 8.6-9.2 |
- 1.7 |
- A |
-
-
- Gecko |
- Netscape Browser 8 |
- Win 98SE+ |
- 1.7 |
- A |
-
-
- Gecko |
- Netscape Navigator 9 |
- Win 98+ / OSX.2+ |
- 1.8 |
- A |
-
-
- Gecko |
- Mozilla 1.0 |
- Win 95+ / OSX.1+ |
- 1 |
- A |
-
-
- Gecko |
- Mozilla 1.1 |
- Win 95+ / OSX.1+ |
- 1.1 |
- A |
-
-
- Gecko |
- Mozilla 1.2 |
- Win 95+ / OSX.1+ |
- 1.2 |
- A |
-
-
- Gecko |
- Mozilla 1.3 |
- Win 95+ / OSX.1+ |
- 1.3 |
- A |
-
-
- Gecko |
- Mozilla 1.4 |
- Win 95+ / OSX.1+ |
- 1.4 |
- A |
-
-
- Gecko |
- Mozilla 1.5 |
- Win 95+ / OSX.1+ |
- 1.5 |
- A |
-
-
- Gecko |
- Mozilla 1.6 |
- Win 95+ / OSX.1+ |
- 1.6 |
- A |
-
-
- Gecko |
- Mozilla 1.7 |
- Win 98+ / OSX.1+ |
- 1.7 |
- A |
-
-
- Gecko |
- Mozilla 1.8 |
- Win 98+ / OSX.1+ |
- 1.8 |
- A |
-
-
- Gecko |
- Seamonkey 1.1 |
- Win 98+ / OSX.2+ |
- 1.8 |
- A |
-
-
- Gecko |
- Epiphany 2.20 |
- Gnome |
- 1.8 |
- A |
-
-
- Webkit |
- Safari 1.2 |
- OSX.3 |
- 125.5 |
- A |
-
-
- Webkit |
- Safari 1.3 |
- OSX.3 |
- 312.8 |
- A |
-
-
- Webkit |
- Safari 2.0 |
- OSX.4+ |
- 419.3 |
- A |
-
-
- Webkit |
- Safari 3.0 |
- OSX.4+ |
- 522.1 |
- A |
-
-
- Webkit |
- OmniWeb 5.5 |
- OSX.4+ |
- 420 |
- A |
-
-
- Webkit |
- iPod Touch / iPhone |
- iPod |
- 420.1 |
- A |
-
-
- Webkit |
- S60 |
- S60 |
- 413 |
- A |
-
-
- Presto |
- Opera 7.0 |
- Win 95+ / OSX.1+ |
- - |
- A |
-
-
- Presto |
- Opera 7.5 |
- Win 95+ / OSX.2+ |
- - |
- A |
-
-
- Presto |
- Opera 8.0 |
- Win 95+ / OSX.2+ |
- - |
- A |
-
-
- Presto |
- Opera 8.5 |
- Win 95+ / OSX.2+ |
- - |
- A |
-
-
- Presto |
- Opera 9.0 |
- Win 95+ / OSX.3+ |
- - |
- A |
-
-
- Presto |
- Opera 9.2 |
- Win 88+ / OSX.3+ |
- - |
- A |
-
-
- Presto |
- Opera 9.5 |
- Win 88+ / OSX.3+ |
- - |
- A |
-
-
- Presto |
- Opera for Wii |
- Wii |
- - |
- A |
-
-
- Presto |
- Nokia N800 |
- N800 |
- - |
- A |
-
-
- Presto |
- Nintendo DS browser |
- Nintendo DS |
- 8.5 |
- C/A1 |
-
-
- KHTML |
- Konqureror 3.1 |
- KDE 3.1 |
- 3.1 |
- C |
-
-
- KHTML |
- Konqureror 3.3 |
- KDE 3.3 |
- 3.3 |
- A |
-
-
- KHTML |
- Konqureror 3.5 |
- KDE 3.5 |
- 3.5 |
- A |
-
-
- Tasman |
- Internet Explorer 4.5 |
- Mac OS 8-9 |
- - |
- X |
-
-
- Tasman |
- Internet Explorer 5.1 |
- Mac OS 7.6-9 |
- 1 |
- C |
-
-
- Tasman |
- Internet Explorer 5.2 |
- Mac OS 8-X |
- 1 |
- C |
-
-
- Misc |
- NetFront 3.1 |
- Embedded devices |
- - |
- C |
-
-
- Misc |
- NetFront 3.4 |
- Embedded devices |
- - |
- A |
-
-
- Misc |
- Dillo 0.8 |
- Embedded devices |
- - |
- X |
-
-
- Misc |
- Links |
- Text only |
- - |
- X |
-
-
- Misc |
- Lynx |
- Text only |
- - |
- X |
-
-
- Misc |
- IE Mobile |
- Windows Mobile 6 |
- - |
- C |
-
-
- Misc |
- PSP browser |
- PSP |
- - |
- C |
-
-
- Other browsers |
- All others |
- - |
- - |
- U |
-
-
-
-
- Rendering engine |
- Browser |
- Platform(s) |
- Engine version |
- CSS grade |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Rendering engine |
- Browser |
- Platform(s) |
- Engine version |
- CSS grade |
-
-
-
-
- Trident |
- Internet
- Explorer 4.0
- |
- Win 95+ |
- 4 |
- X |
-
-
- Trident |
- Internet
- Explorer 5.0
- |
- Win 95+ |
- 5 |
- C |
-
-
- Trident |
- Internet
- Explorer 5.5
- |
- Win 95+ |
- 5.5 |
- A |
-
-
- Trident |
- Internet
- Explorer 6
- |
- Win 98+ |
- 6 |
- A |
-
-
- Trident |
- Internet Explorer 7 |
- Win XP SP2+ |
- 7 |
- A |
-
-
- Trident |
- AOL browser (AOL desktop) |
- Win XP |
- 6 |
- A |
-
-
- Gecko |
- Firefox 1.0 |
- Win 98+ / OSX.2+ |
- 1.7 |
- A |
-
-
- Gecko |
- Firefox 1.5 |
- Win 98+ / OSX.2+ |
- 1.8 |
- A |
-
-
- Gecko |
- Firefox 2.0 |
- Win 98+ / OSX.2+ |
- 1.8 |
- A |
-
-
- Gecko |
- Firefox 3.0 |
- Win 2k+ / OSX.3+ |
- 1.9 |
- A |
-
-
- Gecko |
- Camino 1.0 |
- OSX.2+ |
- 1.8 |
- A |
-
-
- Gecko |
- Camino 1.5 |
- OSX.3+ |
- 1.8 |
- A |
-
-
- Gecko |
- Netscape 7.2 |
- Win 95+ / Mac OS 8.6-9.2 |
- 1.7 |
- A |
-
-
- Gecko |
- Netscape Browser 8 |
- Win 98SE+ |
- 1.7 |
- A |
-
-
- Gecko |
- Netscape Navigator 9 |
- Win 98+ / OSX.2+ |
- 1.8 |
- A |
-
-
- Gecko |
- Mozilla 1.0 |
- Win 95+ / OSX.1+ |
- 1 |
- A |
-
-
- Gecko |
- Mozilla 1.1 |
- Win 95+ / OSX.1+ |
- 1.1 |
- A |
-
-
- Gecko |
- Mozilla 1.2 |
- Win 95+ / OSX.1+ |
- 1.2 |
- A |
-
-
- Gecko |
- Mozilla 1.3 |
- Win 95+ / OSX.1+ |
- 1.3 |
- A |
-
-
- Gecko |
- Mozilla 1.4 |
- Win 95+ / OSX.1+ |
- 1.4 |
- A |
-
-
- Gecko |
- Mozilla 1.5 |
- Win 95+ / OSX.1+ |
- 1.5 |
- A |
-
-
- Gecko |
- Mozilla 1.6 |
- Win 95+ / OSX.1+ |
- 1.6 |
- A |
-
-
- Gecko |
- Mozilla 1.7 |
- Win 98+ / OSX.1+ |
- 1.7 |
- A |
-
-
- Gecko |
- Mozilla 1.8 |
- Win 98+ / OSX.1+ |
- 1.8 |
- A |
-
-
- Gecko |
- Seamonkey 1.1 |
- Win 98+ / OSX.2+ |
- 1.8 |
- A |
-
-
- Gecko |
- Epiphany 2.20 |
- Gnome |
- 1.8 |
- A |
-
-
- Webkit |
- Safari 1.2 |
- OSX.3 |
- 125.5 |
- A |
-
-
- Webkit |
- Safari 1.3 |
- OSX.3 |
- 312.8 |
- A |
-
-
- Webkit |
- Safari 2.0 |
- OSX.4+ |
- 419.3 |
- A |
-
-
- Webkit |
- Safari 3.0 |
- OSX.4+ |
- 522.1 |
- A |
-
-
- Webkit |
- OmniWeb 5.5 |
- OSX.4+ |
- 420 |
- A |
-
-
- Webkit |
- iPod Touch / iPhone |
- iPod |
- 420.1 |
- A |
-
-
- Webkit |
- S60 |
- S60 |
- 413 |
- A |
-
-
- Presto |
- Opera 7.0 |
- Win 95+ / OSX.1+ |
- - |
- A |
-
-
- Presto |
- Opera 7.5 |
- Win 95+ / OSX.2+ |
- - |
- A |
-
-
- Presto |
- Opera 8.0 |
- Win 95+ / OSX.2+ |
- - |
- A |
-
-
- Presto |
- Opera 8.5 |
- Win 95+ / OSX.2+ |
- - |
- A |
-
-
- Presto |
- Opera 9.0 |
- Win 95+ / OSX.3+ |
- - |
- A |
-
-
- Presto |
- Opera 9.2 |
- Win 88+ / OSX.3+ |
- - |
- A |
-
-
- Presto |
- Opera 9.5 |
- Win 88+ / OSX.3+ |
- - |
- A |
-
-
- Presto |
- Opera for Wii |
- Wii |
- - |
- A |
-
-
- Presto |
- Nokia N800 |
- N800 |
- - |
- A |
-
-
- Presto |
- Nintendo DS browser |
- Nintendo DS |
- 8.5 |
- C/A1 |
-
-
- KHTML |
- Konqureror 3.1 |
- KDE 3.1 |
- 3.1 |
- C |
-
-
- KHTML |
- Konqureror 3.3 |
- KDE 3.3 |
- 3.3 |
- A |
-
-
- KHTML |
- Konqureror 3.5 |
- KDE 3.5 |
- 3.5 |
- A |
-
-
- Tasman |
- Internet Explorer 4.5 |
- Mac OS 8-9 |
- - |
- X |
-
-
- Tasman |
- Internet Explorer 5.1 |
- Mac OS 7.6-9 |
- 1 |
- C |
-
-
- Tasman |
- Internet Explorer 5.2 |
- Mac OS 8-X |
- 1 |
- C |
-
-
- Misc |
- NetFront 3.1 |
- Embedded devices |
- - |
- C |
-
-
- Misc |
- NetFront 3.4 |
- Embedded devices |
- - |
- A |
-
-
- Misc |
- Dillo 0.8 |
- Embedded devices |
- - |
- X |
-
-
- Misc |
- Links |
- Text only |
- - |
- X |
-
-
- Misc |
- Lynx |
- Text only |
- - |
- X |
-
-
- Misc |
- IE Mobile |
- Windows Mobile 6 |
- - |
- C |
-
-
- Misc |
- PSP browser |
- PSP |
- - |
- C |
-
-
- Other browsers |
- All others |
- - |
- - |
- U |
-
-
-
-
- Rendering engine |
- Browser |
- Platform(s) |
- Engine version |
- CSS grade |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/tables/simple.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/tables/simple.html
deleted file mode 100644
index 6b18550..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/tables/simple.html
+++ /dev/null
@@ -1,1059 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Simple Tables
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- # |
- Task |
- Progress |
- Label |
-
-
- 1. |
- Update software |
-
-
- |
- 55% |
-
-
- 2. |
- Clean database |
-
-
- |
- 70% |
-
-
- 3. |
- Cron job running |
-
-
- |
- 30% |
-
-
- 4. |
- Fix and squish bugs |
-
-
- |
- 90% |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- # |
- Task |
- Progress |
- Label |
-
-
- 1. |
- Update software |
-
-
- |
- 55% |
-
-
- 2. |
- Clean database |
-
-
- |
- 70% |
-
-
- 3. |
- Cron job running |
-
-
- |
- 30% |
-
-
- 4. |
- Fix and squish bugs |
-
-
- |
- 90% |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- # |
- Task |
- Progress |
- Label |
-
-
- 1. |
- Update software |
-
-
- |
- 55% |
-
-
- 2. |
- Clean database |
-
-
- |
- 70% |
-
-
- 3. |
- Cron job running |
-
-
- |
- 30% |
-
-
- 4. |
- Fix and squish bugs |
-
-
- |
- 90% |
-
-
-
-
-
-
-
-
-
-
-
-
-
- # |
- Task |
- Progress |
- Label |
-
-
- 1. |
- Update software |
-
-
- |
- 55% |
-
-
- 2. |
- Clean database |
-
-
- |
- 70% |
-
-
- 3. |
- Cron job running |
-
-
- |
- 30% |
-
-
- 4. |
- Fix and squish bugs |
-
-
- |
- 90% |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ID |
- User |
- Date |
- Status |
- Reason |
-
-
- 183 |
- John Doe |
- 11-7-2014 |
- Approved |
- Bacon ipsum dolor sit amet salami venison chicken flank fatback doner. |
-
-
- 219 |
- Alexander Pierce |
- 11-7-2014 |
- Pending |
- Bacon ipsum dolor sit amet salami venison chicken flank fatback doner. |
-
-
- 657 |
- Bob Doe |
- 11-7-2014 |
- Approved |
- Bacon ipsum dolor sit amet salami venison chicken flank fatback doner. |
-
-
- 175 |
- Mike Doe |
- 11-7-2014 |
- Denied |
- Bacon ipsum dolor sit amet salami venison chicken flank fatback doner. |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/widgets.html b/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/widgets.html
deleted file mode 100644
index 2bfe69b..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/pages/widgets.html
+++ /dev/null
@@ -1,1791 +0,0 @@
-
-
-
-
-
- AdminLTE 2 | Widgets
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Messages
- 1,410
-
-
-
-
-
-
-
-
-
-
-
- Bookmarks
- 410
-
-
-
-
-
-
-
-
-
-
-
- Uploads
- 13,648
-
-
-
-
-
-
-
-
-
-
-
- Likes
- 93,139
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Bookmarks
-
41,410
-
-
-
- 70% Increase in 30 Days
-
-
-
-
-
-
-
-
-
-
-
-
-
Likes
-
41,410
-
-
-
- 70% Increase in 30 Days
-
-
-
-
-
-
-
-
-
-
-
-
-
Events
-
41,410
-
-
-
- 70% Increase in 30 Days
-
-
-
-
-
-
-
-
-
-
-
-
-
Comments
-
41,410
-
-
-
- 70% Increase in 30 Days
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
44
-
-
User Registrations
-
-
-
-
-
-
-
-
-
-
-
-
-
65
-
-
Unique Visitors
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
-
-
- The body of the box
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alexander Pierce
- 23 Jan 2:00 pm
-
-
-

-
- Is this template really for free? That's unbelievable!
-
-
-
-
-
-
-
-
- Sarah Bullock
- 23 Jan 2:05 pm
-
-
-

-
- You better believe it!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/plugins/bootstrap-slider/bootstrap-slider.js b/power-admin/src/main/webapp/static/bootstrap-3.3.7/plugins/bootstrap-slider/bootstrap-slider.js
deleted file mode 100644
index 3a0e464..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/plugins/bootstrap-slider/bootstrap-slider.js
+++ /dev/null
@@ -1,1576 +0,0 @@
-/*! =========================================================
- * bootstrap-slider.js
- *
- * Maintainers:
- * Kyle Kemp
- * - Twitter: @seiyria
- * - Github: seiyria
- * Rohit Kalkur
- * - Twitter: @Rovolutionary
- * - Github: rovolution
- *
- * =========================================================
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================================================= */
-
-
-/**
- * Bridget makes jQuery widgets
- * v1.0.1
- * MIT license
- */
-
-(function(root, factory) {
- if(typeof define === "function" && define.amd) {
- define(["jquery"], factory);
- }
- else if(typeof module === "object" && module.exports) {
- var jQuery;
- try {
- jQuery = require("jquery");
- }
- catch (err) {
- jQuery = null;
- }
- module.exports = factory(jQuery);
- }
- else {
- root.Slider = factory(root.jQuery);
- }
-}(this, function($) {
- // Reference to Slider constructor
- var Slider;
-
-
- (function( $ ) {
-
- 'use strict';
-
- // -------------------------- utils -------------------------- //
-
- var slice = Array.prototype.slice;
-
- function noop() {}
-
- // -------------------------- definition -------------------------- //
-
- function defineBridget( $ ) {
-
- // bail if no jQuery
- if ( !$ ) {
- return;
- }
-
- // -------------------------- addOptionMethod -------------------------- //
-
- /**
- * adds option method -> $().plugin('option', {...})
- * @param {Function} PluginClass - constructor class
- */
- function addOptionMethod( PluginClass ) {
- // don't overwrite original option method
- if ( PluginClass.prototype.option ) {
- return;
- }
-
- // option setter
- PluginClass.prototype.option = function( opts ) {
- // bail out if not an object
- if ( !$.isPlainObject( opts ) ){
- return;
- }
- this.options = $.extend( true, this.options, opts );
- };
- }
-
-
- // -------------------------- plugin bridge -------------------------- //
-
- // helper function for logging errors
- // $.error breaks jQuery chaining
- var logError = typeof console === 'undefined' ? noop :
- function( message ) {
- console.error( message );
- };
-
- /**
- * jQuery plugin bridge, access methods like $elem.plugin('method')
- * @param {String} namespace - plugin name
- * @param {Function} PluginClass - constructor class
- */
- function bridge( namespace, PluginClass ) {
- // add to jQuery fn namespace
- $.fn[ namespace ] = function( options ) {
- if ( typeof options === 'string' ) {
- // call plugin method when first argument is a string
- // get arguments for method
- var args = slice.call( arguments, 1 );
-
- for ( var i=0, len = this.length; i < len; i++ ) {
- var elem = this[i];
- var instance = $.data( elem, namespace );
- if ( !instance ) {
- logError( "cannot call methods on " + namespace + " prior to initialization; " +
- "attempted to call '" + options + "'" );
- continue;
- }
- if ( !$.isFunction( instance[options] ) || options.charAt(0) === '_' ) {
- logError( "no such method '" + options + "' for " + namespace + " instance" );
- continue;
- }
-
- // trigger method with arguments
- var returnValue = instance[ options ].apply( instance, args);
-
- // break look and return first value if provided
- if ( returnValue !== undefined && returnValue !== instance) {
- return returnValue;
- }
- }
- // return this if no return value
- return this;
- } else {
- var objects = this.map( function() {
- var instance = $.data( this, namespace );
- if ( instance ) {
- // apply options & init
- instance.option( options );
- instance._init();
- } else {
- // initialize new instance
- instance = new PluginClass( this, options );
- $.data( this, namespace, instance );
- }
- return $(this);
- });
-
- if(!objects || objects.length > 1) {
- return objects;
- } else {
- return objects[0];
- }
- }
- };
-
- }
-
- // -------------------------- bridget -------------------------- //
-
- /**
- * converts a Prototypical class into a proper jQuery plugin
- * the class must have a ._init method
- * @param {String} namespace - plugin name, used in $().pluginName
- * @param {Function} PluginClass - constructor class
- */
- $.bridget = function( namespace, PluginClass ) {
- addOptionMethod( PluginClass );
- bridge( namespace, PluginClass );
- };
-
- return $.bridget;
-
- }
-
- // get jquery from browser global
- defineBridget( $ );
-
- })( $ );
-
-
- /*************************************************
-
- BOOTSTRAP-SLIDER SOURCE CODE
-
- **************************************************/
-
- (function($) {
-
- var ErrorMsgs = {
- formatInvalidInputErrorMsg : function(input) {
- return "Invalid input value '" + input + "' passed in";
- },
- callingContextNotSliderInstance : "Calling context element does not have instance of Slider bound to it. Check your code to make sure the JQuery object returned from the call to the slider() initializer is calling the method"
- };
-
- var SliderScale = {
- linear: {
- toValue: function(percentage) {
- var rawValue = percentage/100 * (this.options.max - this.options.min);
- if (this.options.ticks_positions.length > 0) {
- var minv, maxv, minp, maxp = 0;
- for (var i = 0; i < this.options.ticks_positions.length; i++) {
- if (percentage <= this.options.ticks_positions[i]) {
- minv = (i > 0) ? this.options.ticks[i-1] : 0;
- minp = (i > 0) ? this.options.ticks_positions[i-1] : 0;
- maxv = this.options.ticks[i];
- maxp = this.options.ticks_positions[i];
-
- break;
- }
- }
- if (i > 0) {
- var partialPercentage = (percentage - minp) / (maxp - minp);
- rawValue = minv + partialPercentage * (maxv - minv);
- }
- }
-
- var value = this.options.min + Math.round(rawValue / this.options.step) * this.options.step;
- if (value < this.options.min) {
- return this.options.min;
- } else if (value > this.options.max) {
- return this.options.max;
- } else {
- return value;
- }
- },
- toPercentage: function(value) {
- if (this.options.max === this.options.min) {
- return 0;
- }
-
- if (this.options.ticks_positions.length > 0) {
- var minv, maxv, minp, maxp = 0;
- for (var i = 0; i < this.options.ticks.length; i++) {
- if (value <= this.options.ticks[i]) {
- minv = (i > 0) ? this.options.ticks[i-1] : 0;
- minp = (i > 0) ? this.options.ticks_positions[i-1] : 0;
- maxv = this.options.ticks[i];
- maxp = this.options.ticks_positions[i];
-
- break;
- }
- }
- if (i > 0) {
- var partialPercentage = (value - minv) / (maxv - minv);
- return minp + partialPercentage * (maxp - minp);
- }
- }
-
- return 100 * (value - this.options.min) / (this.options.max - this.options.min);
- }
- },
-
- logarithmic: {
- /* Based on http://stackoverflow.com/questions/846221/logarithmic-slider */
- toValue: function(percentage) {
- var min = (this.options.min === 0) ? 0 : Math.log(this.options.min);
- var max = Math.log(this.options.max);
- var value = Math.exp(min + (max - min) * percentage / 100);
- value = this.options.min + Math.round((value - this.options.min) / this.options.step) * this.options.step;
- /* Rounding to the nearest step could exceed the min or
- * max, so clip to those values. */
- if (value < this.options.min) {
- return this.options.min;
- } else if (value > this.options.max) {
- return this.options.max;
- } else {
- return value;
- }
- },
- toPercentage: function(value) {
- if (this.options.max === this.options.min) {
- return 0;
- } else {
- var max = Math.log(this.options.max);
- var min = this.options.min === 0 ? 0 : Math.log(this.options.min);
- var v = value === 0 ? 0 : Math.log(value);
- return 100 * (v - min) / (max - min);
- }
- }
- }
- };
-
-
- /*************************************************
-
- CONSTRUCTOR
-
- **************************************************/
- Slider = function(element, options) {
- createNewSlider.call(this, element, options);
- return this;
- };
-
- function createNewSlider(element, options) {
-
- /*
- The internal state object is used to store data about the current 'state' of slider.
-
- This includes values such as the `value`, `enabled`, etc...
- */
- this._state = {
- value: null,
- enabled: null,
- offset: null,
- size: null,
- percentage: null,
- inDrag: false,
- over: false
- };
-
-
- if(typeof element === "string") {
- this.element = document.querySelector(element);
- } else if(element instanceof HTMLElement) {
- this.element = element;
- }
-
- /*************************************************
-
- Process Options
-
- **************************************************/
- options = options ? options : {};
- var optionTypes = Object.keys(this.defaultOptions);
-
- for(var i = 0; i < optionTypes.length; i++) {
- var optName = optionTypes[i];
-
- // First check if an option was passed in via the constructor
- var val = options[optName];
- // If no data attrib, then check data atrributes
- val = (typeof val !== 'undefined') ? val : getDataAttrib(this.element, optName);
- // Finally, if nothing was specified, use the defaults
- val = (val !== null) ? val : this.defaultOptions[optName];
-
- // Set all options on the instance of the Slider
- if(!this.options) {
- this.options = {};
- }
- this.options[optName] = val;
- }
-
- /*
- Validate `tooltip_position` against 'orientation`
- - if `tooltip_position` is incompatible with orientation, swith it to a default compatible with specified `orientation`
- -- default for "vertical" -> "right"
- -- default for "horizontal" -> "left"
- */
- if(this.options.orientation === "vertical" && (this.options.tooltip_position === "top" || this.options.tooltip_position === "bottom")) {
-
- this.options.tooltip_position = "right";
-
- }
- else if(this.options.orientation === "horizontal" && (this.options.tooltip_position === "left" || this.options.tooltip_position === "right")) {
-
- this.options.tooltip_position = "top";
-
- }
-
- function getDataAttrib(element, optName) {
- var dataName = "data-slider-" + optName.replace(/_/g, '-');
- var dataValString = element.getAttribute(dataName);
-
- try {
- return JSON.parse(dataValString);
- }
- catch(err) {
- return dataValString;
- }
- }
-
- /*************************************************
-
- Create Markup
-
- **************************************************/
-
- var origWidth = this.element.style.width;
- var updateSlider = false;
- var parent = this.element.parentNode;
- var sliderTrackSelection;
- var sliderTrackLow, sliderTrackHigh;
- var sliderMinHandle;
- var sliderMaxHandle;
-
- if (this.sliderElem) {
- updateSlider = true;
- } else {
- /* Create elements needed for slider */
- this.sliderElem = document.createElement("div");
- this.sliderElem.className = "slider";
-
- /* Create slider track elements */
- var sliderTrack = document.createElement("div");
- sliderTrack.className = "slider-track";
-
- sliderTrackLow = document.createElement("div");
- sliderTrackLow.className = "slider-track-low";
-
- sliderTrackSelection = document.createElement("div");
- sliderTrackSelection.className = "slider-selection";
-
- sliderTrackHigh = document.createElement("div");
- sliderTrackHigh.className = "slider-track-high";
-
- sliderMinHandle = document.createElement("div");
- sliderMinHandle.className = "slider-handle min-slider-handle";
- sliderMinHandle.setAttribute('role', 'slider');
- sliderMinHandle.setAttribute('aria-valuemin', this.options.min);
- sliderMinHandle.setAttribute('aria-valuemax', this.options.max);
-
- sliderMaxHandle = document.createElement("div");
- sliderMaxHandle.className = "slider-handle max-slider-handle";
- sliderMaxHandle.setAttribute('role', 'slider');
- sliderMaxHandle.setAttribute('aria-valuemin', this.options.min);
- sliderMaxHandle.setAttribute('aria-valuemax', this.options.max);
-
- sliderTrack.appendChild(sliderTrackLow);
- sliderTrack.appendChild(sliderTrackSelection);
- sliderTrack.appendChild(sliderTrackHigh);
-
- /* Add aria-labelledby to handle's */
- var isLabelledbyArray = Array.isArray(this.options.labelledby);
- if (isLabelledbyArray && this.options.labelledby[0]) {
- sliderMinHandle.setAttribute('aria-labelledby', this.options.labelledby[0]);
- }
- if (isLabelledbyArray && this.options.labelledby[1]) {
- sliderMaxHandle.setAttribute('aria-labelledby', this.options.labelledby[1]);
- }
- if (!isLabelledbyArray && this.options.labelledby) {
- sliderMinHandle.setAttribute('aria-labelledby', this.options.labelledby);
- sliderMaxHandle.setAttribute('aria-labelledby', this.options.labelledby);
- }
-
- /* Create ticks */
- this.ticks = [];
- if (Array.isArray(this.options.ticks) && this.options.ticks.length > 0) {
- for (i = 0; i < this.options.ticks.length; i++) {
- var tick = document.createElement('div');
- tick.className = 'slider-tick';
-
- this.ticks.push(tick);
- sliderTrack.appendChild(tick);
- }
-
- sliderTrackSelection.className += " tick-slider-selection";
- }
-
- sliderTrack.appendChild(sliderMinHandle);
- sliderTrack.appendChild(sliderMaxHandle);
-
- this.tickLabels = [];
- if (Array.isArray(this.options.ticks_labels) && this.options.ticks_labels.length > 0) {
- this.tickLabelContainer = document.createElement('div');
- this.tickLabelContainer.className = 'slider-tick-label-container';
-
- for (i = 0; i < this.options.ticks_labels.length; i++) {
- var label = document.createElement('div');
- var noTickPositionsSpecified = this.options.ticks_positions.length === 0;
- var tickLabelsIndex = (this.options.reversed && noTickPositionsSpecified) ? (this.options.ticks_labels.length - (i + 1)) : i;
- label.className = 'slider-tick-label';
- label.innerHTML = this.options.ticks_labels[tickLabelsIndex];
-
- this.tickLabels.push(label);
- this.tickLabelContainer.appendChild(label);
- }
- }
-
-
- var createAndAppendTooltipSubElements = function(tooltipElem) {
- var arrow = document.createElement("div");
- arrow.className = "tooltip-arrow";
-
- var inner = document.createElement("div");
- inner.className = "tooltip-inner";
-
- tooltipElem.appendChild(arrow);
- tooltipElem.appendChild(inner);
-
- };
-
- /* Create tooltip elements */
- var sliderTooltip = document.createElement("div");
- sliderTooltip.className = "tooltip tooltip-main";
- sliderTooltip.setAttribute('role', 'presentation');
- createAndAppendTooltipSubElements(sliderTooltip);
-
- var sliderTooltipMin = document.createElement("div");
- sliderTooltipMin.className = "tooltip tooltip-min";
- sliderTooltipMin.setAttribute('role', 'presentation');
- createAndAppendTooltipSubElements(sliderTooltipMin);
-
- var sliderTooltipMax = document.createElement("div");
- sliderTooltipMax.className = "tooltip tooltip-max";
- sliderTooltipMax.setAttribute('role', 'presentation');
- createAndAppendTooltipSubElements(sliderTooltipMax);
-
-
- /* Append components to sliderElem */
- this.sliderElem.appendChild(sliderTrack);
- this.sliderElem.appendChild(sliderTooltip);
- this.sliderElem.appendChild(sliderTooltipMin);
- this.sliderElem.appendChild(sliderTooltipMax);
-
- if (this.tickLabelContainer) {
- this.sliderElem.appendChild(this.tickLabelContainer);
- }
-
- /* Append slider element to parent container, right before the original element */
- parent.insertBefore(this.sliderElem, this.element);
-
- /* Hide original element */
- this.element.style.display = "none";
- }
- /* If JQuery exists, cache JQ references */
- if($) {
- this.$element = $(this.element);
- this.$sliderElem = $(this.sliderElem);
- }
-
- /*************************************************
-
- Setup
-
- **************************************************/
- this.eventToCallbackMap = {};
- this.sliderElem.id = this.options.id;
-
- this.touchCapable = 'ontouchstart' in window || (window.DocumentTouch && document instanceof window.DocumentTouch);
-
- this.tooltip = this.sliderElem.querySelector('.tooltip-main');
- this.tooltipInner = this.tooltip.querySelector('.tooltip-inner');
-
- this.tooltip_min = this.sliderElem.querySelector('.tooltip-min');
- this.tooltipInner_min = this.tooltip_min.querySelector('.tooltip-inner');
-
- this.tooltip_max = this.sliderElem.querySelector('.tooltip-max');
- this.tooltipInner_max= this.tooltip_max.querySelector('.tooltip-inner');
-
- if (SliderScale[this.options.scale]) {
- this.options.scale = SliderScale[this.options.scale];
- }
-
- if (updateSlider === true) {
- // Reset classes
- this._removeClass(this.sliderElem, 'slider-horizontal');
- this._removeClass(this.sliderElem, 'slider-vertical');
- this._removeClass(this.tooltip, 'hide');
- this._removeClass(this.tooltip_min, 'hide');
- this._removeClass(this.tooltip_max, 'hide');
-
- // Undo existing inline styles for track
- ["left", "top", "width", "height"].forEach(function(prop) {
- this._removeProperty(this.trackLow, prop);
- this._removeProperty(this.trackSelection, prop);
- this._removeProperty(this.trackHigh, prop);
- }, this);
-
- // Undo inline styles on handles
- [this.handle1, this.handle2].forEach(function(handle) {
- this._removeProperty(handle, 'left');
- this._removeProperty(handle, 'top');
- }, this);
-
- // Undo inline styles and classes on tooltips
- [this.tooltip, this.tooltip_min, this.tooltip_max].forEach(function(tooltip) {
- this._removeProperty(tooltip, 'left');
- this._removeProperty(tooltip, 'top');
- this._removeProperty(tooltip, 'margin-left');
- this._removeProperty(tooltip, 'margin-top');
-
- this._removeClass(tooltip, 'right');
- this._removeClass(tooltip, 'top');
- }, this);
- }
-
- if(this.options.orientation === 'vertical') {
- this._addClass(this.sliderElem,'slider-vertical');
- this.stylePos = 'top';
- this.mousePos = 'pageY';
- this.sizePos = 'offsetHeight';
- } else {
- this._addClass(this.sliderElem, 'slider-horizontal');
- this.sliderElem.style.width = origWidth;
- this.options.orientation = 'horizontal';
- this.stylePos = 'left';
- this.mousePos = 'pageX';
- this.sizePos = 'offsetWidth';
-
- }
- this._setTooltipPosition();
- /* In case ticks are specified, overwrite the min and max bounds */
- if (Array.isArray(this.options.ticks) && this.options.ticks.length > 0) {
- this.options.max = Math.max.apply(Math, this.options.ticks);
- this.options.min = Math.min.apply(Math, this.options.ticks);
- }
-
- if (Array.isArray(this.options.value)) {
- this.options.range = true;
- this._state.value = this.options.value;
- }
- else if (this.options.range) {
- // User wants a range, but value is not an array
- this._state.value = [this.options.value, this.options.max];
- }
- else {
- this._state.value = this.options.value;
- }
-
- this.trackLow = sliderTrackLow || this.trackLow;
- this.trackSelection = sliderTrackSelection || this.trackSelection;
- this.trackHigh = sliderTrackHigh || this.trackHigh;
-
- if (this.options.selection === 'none') {
- this._addClass(this.trackLow, 'hide');
- this._addClass(this.trackSelection, 'hide');
- this._addClass(this.trackHigh, 'hide');
- }
-
- this.handle1 = sliderMinHandle || this.handle1;
- this.handle2 = sliderMaxHandle || this.handle2;
-
- if (updateSlider === true) {
- // Reset classes
- this._removeClass(this.handle1, 'round triangle');
- this._removeClass(this.handle2, 'round triangle hide');
-
- for (i = 0; i < this.ticks.length; i++) {
- this._removeClass(this.ticks[i], 'round triangle hide');
- }
- }
-
- var availableHandleModifiers = ['round', 'triangle', 'custom'];
- var isValidHandleType = availableHandleModifiers.indexOf(this.options.handle) !== -1;
- if (isValidHandleType) {
- this._addClass(this.handle1, this.options.handle);
- this._addClass(this.handle2, this.options.handle);
-
- for (i = 0; i < this.ticks.length; i++) {
- this._addClass(this.ticks[i], this.options.handle);
- }
- }
-
- this._state.offset = this._offset(this.sliderElem);
- this._state.size = this.sliderElem[this.sizePos];
- this.setValue(this._state.value);
-
- /******************************************
-
- Bind Event Listeners
-
- ******************************************/
-
- // Bind keyboard handlers
- this.handle1Keydown = this._keydown.bind(this, 0);
- this.handle1.addEventListener("keydown", this.handle1Keydown, false);
-
- this.handle2Keydown = this._keydown.bind(this, 1);
- this.handle2.addEventListener("keydown", this.handle2Keydown, false);
-
- this.mousedown = this._mousedown.bind(this);
- if (this.touchCapable) {
- // Bind touch handlers
- this.sliderElem.addEventListener("touchstart", this.mousedown, false);
- }
- this.sliderElem.addEventListener("mousedown", this.mousedown, false);
-
-
- // Bind tooltip-related handlers
- if(this.options.tooltip === 'hide') {
- this._addClass(this.tooltip, 'hide');
- this._addClass(this.tooltip_min, 'hide');
- this._addClass(this.tooltip_max, 'hide');
- }
- else if(this.options.tooltip === 'always') {
- this._showTooltip();
- this._alwaysShowTooltip = true;
- }
- else {
- this.showTooltip = this._showTooltip.bind(this);
- this.hideTooltip = this._hideTooltip.bind(this);
-
- this.sliderElem.addEventListener("mouseenter", this.showTooltip, false);
- this.sliderElem.addEventListener("mouseleave", this.hideTooltip, false);
-
- this.handle1.addEventListener("focus", this.showTooltip, false);
- this.handle1.addEventListener("blur", this.hideTooltip, false);
-
- this.handle2.addEventListener("focus", this.showTooltip, false);
- this.handle2.addEventListener("blur", this.hideTooltip, false);
- }
-
- if(this.options.enabled) {
- this.enable();
- } else {
- this.disable();
- }
- }
-
-
-
- /*************************************************
-
- INSTANCE PROPERTIES/METHODS
-
- - Any methods bound to the prototype are considered
- part of the plugin's `public` interface
-
- **************************************************/
- Slider.prototype = {
- _init: function() {}, // NOTE: Must exist to support bridget
-
- constructor: Slider,
-
- defaultOptions: {
- id: "",
- min: 0,
- max: 10,
- step: 1,
- precision: 0,
- orientation: 'horizontal',
- value: 5,
- range: false,
- selection: 'before',
- tooltip: 'show',
- tooltip_split: false,
- handle: 'round',
- reversed: false,
- enabled: true,
- formatter: function(val) {
- if (Array.isArray(val)) {
- return val[0] + " : " + val[1];
- } else {
- return val;
- }
- },
- natural_arrow_keys: false,
- ticks: [],
- ticks_positions: [],
- ticks_labels: [],
- ticks_snap_bounds: 0,
- scale: 'linear',
- focus: false,
- tooltip_position: null,
- labelledby: null
- },
-
- getElement: function() {
- return this.sliderElem;
- },
-
- getValue: function() {
- if (this.options.range) {
- return this._state.value;
- }
- else {
- return this._state.value[0];
- }
- },
-
- setValue: function(val, triggerSlideEvent, triggerChangeEvent) {
- if (!val) {
- val = 0;
- }
- var oldValue = this.getValue();
- this._state.value = this._validateInputValue(val);
- var applyPrecision = this._applyPrecision.bind(this);
-
- if (this.options.range) {
- this._state.value[0] = applyPrecision(this._state.value[0]);
- this._state.value[1] = applyPrecision(this._state.value[1]);
-
- this._state.value[0] = Math.max(this.options.min, Math.min(this.options.max, this._state.value[0]));
- this._state.value[1] = Math.max(this.options.min, Math.min(this.options.max, this._state.value[1]));
- }
- else {
- this._state.value = applyPrecision(this._state.value);
- this._state.value = [ Math.max(this.options.min, Math.min(this.options.max, this._state.value))];
- this._addClass(this.handle2, 'hide');
- if (this.options.selection === 'after') {
- this._state.value[1] = this.options.max;
- } else {
- this._state.value[1] = this.options.min;
- }
- }
-
- if (this.options.max > this.options.min) {
- this._state.percentage = [
- this._toPercentage(this._state.value[0]),
- this._toPercentage(this._state.value[1]),
- this.options.step * 100 / (this.options.max - this.options.min)
- ];
- } else {
- this._state.percentage = [0, 0, 100];
- }
-
- this._layout();
- var newValue = this.options.range ? this._state.value : this._state.value[0];
-
- if(triggerSlideEvent === true) {
- this._trigger('slide', newValue);
- }
- if( (oldValue !== newValue) && (triggerChangeEvent === true) ) {
- this._trigger('change', {
- oldValue: oldValue,
- newValue: newValue
- });
- }
- this._setDataVal(newValue);
-
- return this;
- },
-
- destroy: function(){
- // Remove event handlers on slider elements
- this._removeSliderEventHandlers();
-
- // Remove the slider from the DOM
- this.sliderElem.parentNode.removeChild(this.sliderElem);
- /* Show original element */
- this.element.style.display = "";
-
- // Clear out custom event bindings
- this._cleanUpEventCallbacksMap();
-
- // Remove data values
- this.element.removeAttribute("data");
-
- // Remove JQuery handlers/data
- if($) {
- this._unbindJQueryEventHandlers();
- this.$element.removeData('slider');
- }
- },
-
- disable: function() {
- this._state.enabled = false;
- this.handle1.removeAttribute("tabindex");
- this.handle2.removeAttribute("tabindex");
- this._addClass(this.sliderElem, 'slider-disabled');
- this._trigger('slideDisabled');
-
- return this;
- },
-
- enable: function() {
- this._state.enabled = true;
- this.handle1.setAttribute("tabindex", 0);
- this.handle2.setAttribute("tabindex", 0);
- this._removeClass(this.sliderElem, 'slider-disabled');
- this._trigger('slideEnabled');
-
- return this;
- },
-
- toggle: function() {
- if(this._state.enabled) {
- this.disable();
- } else {
- this.enable();
- }
- return this;
- },
-
- isEnabled: function() {
- return this._state.enabled;
- },
-
- on: function(evt, callback) {
- this._bindNonQueryEventHandler(evt, callback);
- return this;
- },
-
- off: function(evt, callback) {
- if($) {
- this.$element.off(evt, callback);
- this.$sliderElem.off(evt, callback);
- } else {
- this._unbindNonQueryEventHandler(evt, callback);
- }
- },
-
- getAttribute: function(attribute) {
- if(attribute) {
- return this.options[attribute];
- } else {
- return this.options;
- }
- },
-
- setAttribute: function(attribute, value) {
- this.options[attribute] = value;
- return this;
- },
-
- refresh: function() {
- this._removeSliderEventHandlers();
- createNewSlider.call(this, this.element, this.options);
- if($) {
- // Bind new instance of slider to the element
- $.data(this.element, 'slider', this);
- }
- return this;
- },
-
- relayout: function() {
- this._layout();
- return this;
- },
-
- /******************************+
-
- HELPERS
-
- - Any method that is not part of the public interface.
- - Place it underneath this comment block and write its signature like so:
-
- _fnName : function() {...}
-
- ********************************/
- _removeSliderEventHandlers: function() {
- // Remove keydown event listeners
- this.handle1.removeEventListener("keydown", this.handle1Keydown, false);
- this.handle2.removeEventListener("keydown", this.handle2Keydown, false);
-
- if (this.showTooltip) {
- this.handle1.removeEventListener("focus", this.showTooltip, false);
- this.handle2.removeEventListener("focus", this.showTooltip, false);
- }
- if (this.hideTooltip) {
- this.handle1.removeEventListener("blur", this.hideTooltip, false);
- this.handle2.removeEventListener("blur", this.hideTooltip, false);
- }
-
- // Remove event listeners from sliderElem
- if (this.showTooltip) {
- this.sliderElem.removeEventListener("mouseenter", this.showTooltip, false);
- }
- if (this.hideTooltip) {
- this.sliderElem.removeEventListener("mouseleave", this.hideTooltip, false);
- }
- this.sliderElem.removeEventListener("touchstart", this.mousedown, false);
- this.sliderElem.removeEventListener("mousedown", this.mousedown, false);
- },
- _bindNonQueryEventHandler: function(evt, callback) {
- if(this.eventToCallbackMap[evt] === undefined) {
- this.eventToCallbackMap[evt] = [];
- }
- this.eventToCallbackMap[evt].push(callback);
- },
- _unbindNonQueryEventHandler: function(evt, callback) {
- var callbacks = this.eventToCallbackMap[evt];
- if(callbacks !== undefined) {
- for (var i = 0; i < callbacks.length; i++) {
- if (callbacks[i] === callback) {
- callbacks.splice(i, 1);
- break;
- }
- }
- }
- },
- _cleanUpEventCallbacksMap: function() {
- var eventNames = Object.keys(this.eventToCallbackMap);
- for(var i = 0; i < eventNames.length; i++) {
- var eventName = eventNames[i];
- this.eventToCallbackMap[eventName] = null;
- }
- },
- _showTooltip: function() {
- if (this.options.tooltip_split === false ){
- this._addClass(this.tooltip, 'in');
- this.tooltip_min.style.display = 'none';
- this.tooltip_max.style.display = 'none';
- } else {
- this._addClass(this.tooltip_min, 'in');
- this._addClass(this.tooltip_max, 'in');
- this.tooltip.style.display = 'none';
- }
- this._state.over = true;
- },
- _hideTooltip: function() {
- if (this._state.inDrag === false && this.alwaysShowTooltip !== true) {
- this._removeClass(this.tooltip, 'in');
- this._removeClass(this.tooltip_min, 'in');
- this._removeClass(this.tooltip_max, 'in');
- }
- this._state.over = false;
- },
- _layout: function() {
- var positionPercentages;
-
- if(this.options.reversed) {
- positionPercentages = [ 100 - this._state.percentage[0], this.options.range ? 100 - this._state.percentage[1] : this._state.percentage[1]];
- }
- else {
- positionPercentages = [ this._state.percentage[0], this._state.percentage[1] ];
- }
-
- this.handle1.style[this.stylePos] = positionPercentages[0]+'%';
- this.handle1.setAttribute('aria-valuenow', this._state.value[0]);
-
- this.handle2.style[this.stylePos] = positionPercentages[1]+'%';
- this.handle2.setAttribute('aria-valuenow', this._state.value[1]);
-
- /* Position ticks and labels */
- if (Array.isArray(this.options.ticks) && this.options.ticks.length > 0) {
-
- var styleSize = this.options.orientation === 'vertical' ? 'height' : 'width';
- var styleMargin = this.options.orientation === 'vertical' ? 'marginTop' : 'marginLeft';
- var labelSize = this._state.size / (this.options.ticks.length - 1);
-
- if (this.tickLabelContainer) {
- var extraMargin = 0;
- if (this.options.ticks_positions.length === 0) {
- if (this.options.orientation !== 'vertical') {
- this.tickLabelContainer.style[styleMargin] = -labelSize/2 + 'px';
- }
-
- extraMargin = this.tickLabelContainer.offsetHeight;
- } else {
- /* Chidren are position absolute, calculate height by finding the max offsetHeight of a child */
- for (i = 0 ; i < this.tickLabelContainer.childNodes.length; i++) {
- if (this.tickLabelContainer.childNodes[i].offsetHeight > extraMargin) {
- extraMargin = this.tickLabelContainer.childNodes[i].offsetHeight;
- }
- }
- }
- if (this.options.orientation === 'horizontal') {
- this.sliderElem.style.marginBottom = extraMargin + 'px';
- }
- }
- for (var i = 0; i < this.options.ticks.length; i++) {
-
- var percentage = this.options.ticks_positions[i] || this._toPercentage(this.options.ticks[i]);
-
- if (this.options.reversed) {
- percentage = 100 - percentage;
- }
-
- this.ticks[i].style[this.stylePos] = percentage + '%';
-
- /* Set class labels to denote whether ticks are in the selection */
- this._removeClass(this.ticks[i], 'in-selection');
- if (!this.options.range) {
- if (this.options.selection === 'after' && percentage >= positionPercentages[0]){
- this._addClass(this.ticks[i], 'in-selection');
- } else if (this.options.selection === 'before' && percentage <= positionPercentages[0]) {
- this._addClass(this.ticks[i], 'in-selection');
- }
- } else if (percentage >= positionPercentages[0] && percentage <= positionPercentages[1]) {
- this._addClass(this.ticks[i], 'in-selection');
- }
-
- if (this.tickLabels[i]) {
- this.tickLabels[i].style[styleSize] = labelSize + 'px';
-
- if (this.options.orientation !== 'vertical' && this.options.ticks_positions[i] !== undefined) {
- this.tickLabels[i].style.position = 'absolute';
- this.tickLabels[i].style[this.stylePos] = percentage + '%';
- this.tickLabels[i].style[styleMargin] = -labelSize/2 + 'px';
- } else if (this.options.orientation === 'vertical') {
- this.tickLabels[i].style['marginLeft'] = this.sliderElem.offsetWidth + 'px';
- this.tickLabelContainer.style['marginTop'] = this.sliderElem.offsetWidth / 2 * -1 + 'px';
- }
- }
- }
- }
-
- var formattedTooltipVal;
-
- if (this.options.range) {
- formattedTooltipVal = this.options.formatter(this._state.value);
- this._setText(this.tooltipInner, formattedTooltipVal);
- this.tooltip.style[this.stylePos] = (positionPercentages[1] + positionPercentages[0])/2 + '%';
-
- if (this.options.orientation === 'vertical') {
- this._css(this.tooltip, 'margin-top', -this.tooltip.offsetHeight / 2 + 'px');
- } else {
- this._css(this.tooltip, 'margin-left', -this.tooltip.offsetWidth / 2 + 'px');
- }
-
- if (this.options.orientation === 'vertical') {
- this._css(this.tooltip, 'margin-top', -this.tooltip.offsetHeight / 2 + 'px');
- } else {
- this._css(this.tooltip, 'margin-left', -this.tooltip.offsetWidth / 2 + 'px');
- }
-
- var innerTooltipMinText = this.options.formatter(this._state.value[0]);
- this._setText(this.tooltipInner_min, innerTooltipMinText);
-
- var innerTooltipMaxText = this.options.formatter(this._state.value[1]);
- this._setText(this.tooltipInner_max, innerTooltipMaxText);
-
- this.tooltip_min.style[this.stylePos] = positionPercentages[0] + '%';
-
- if (this.options.orientation === 'vertical') {
- this._css(this.tooltip_min, 'margin-top', -this.tooltip_min.offsetHeight / 2 + 'px');
- } else {
- this._css(this.tooltip_min, 'margin-left', -this.tooltip_min.offsetWidth / 2 + 'px');
- }
-
- this.tooltip_max.style[this.stylePos] = positionPercentages[1] + '%';
-
- if (this.options.orientation === 'vertical') {
- this._css(this.tooltip_max, 'margin-top', -this.tooltip_max.offsetHeight / 2 + 'px');
- } else {
- this._css(this.tooltip_max, 'margin-left', -this.tooltip_max.offsetWidth / 2 + 'px');
- }
- } else {
- formattedTooltipVal = this.options.formatter(this._state.value[0]);
- this._setText(this.tooltipInner, formattedTooltipVal);
-
- this.tooltip.style[this.stylePos] = positionPercentages[0] + '%';
- if (this.options.orientation === 'vertical') {
- this._css(this.tooltip, 'margin-top', -this.tooltip.offsetHeight / 2 + 'px');
- } else {
- this._css(this.tooltip, 'margin-left', -this.tooltip.offsetWidth / 2 + 'px');
- }
- }
-
- if (this.options.orientation === 'vertical') {
- this.trackLow.style.top = '0';
- this.trackLow.style.height = Math.min(positionPercentages[0], positionPercentages[1]) +'%';
-
- this.trackSelection.style.top = Math.min(positionPercentages[0], positionPercentages[1]) +'%';
- this.trackSelection.style.height = Math.abs(positionPercentages[0] - positionPercentages[1]) +'%';
-
- this.trackHigh.style.bottom = '0';
- this.trackHigh.style.height = (100 - Math.min(positionPercentages[0], positionPercentages[1]) - Math.abs(positionPercentages[0] - positionPercentages[1])) +'%';
- }
- else {
- this.trackLow.style.left = '0';
- this.trackLow.style.width = Math.min(positionPercentages[0], positionPercentages[1]) +'%';
-
- this.trackSelection.style.left = Math.min(positionPercentages[0], positionPercentages[1]) +'%';
- this.trackSelection.style.width = Math.abs(positionPercentages[0] - positionPercentages[1]) +'%';
-
- this.trackHigh.style.right = '0';
- this.trackHigh.style.width = (100 - Math.min(positionPercentages[0], positionPercentages[1]) - Math.abs(positionPercentages[0] - positionPercentages[1])) +'%';
-
- var offset_min = this.tooltip_min.getBoundingClientRect();
- var offset_max = this.tooltip_max.getBoundingClientRect();
-
- if (offset_min.right > offset_max.left) {
- this._removeClass(this.tooltip_max, 'top');
- this._addClass(this.tooltip_max, 'bottom');
- this.tooltip_max.style.top = 18 + 'px';
- } else {
- this._removeClass(this.tooltip_max, 'bottom');
- this._addClass(this.tooltip_max, 'top');
- this.tooltip_max.style.top = this.tooltip_min.style.top;
- }
- }
- },
- _removeProperty: function(element, prop) {
- if (element.style.removeProperty) {
- element.style.removeProperty(prop);
- } else {
- element.style.removeAttribute(prop);
- }
- },
- _mousedown: function(ev) {
- if(!this._state.enabled) {
- return false;
- }
-
- this._state.offset = this._offset(this.sliderElem);
- this._state.size = this.sliderElem[this.sizePos];
-
- var percentage = this._getPercentage(ev);
-
- if (this.options.range) {
- var diff1 = Math.abs(this._state.percentage[0] - percentage);
- var diff2 = Math.abs(this._state.percentage[1] - percentage);
- this._state.dragged = (diff1 < diff2) ? 0 : 1;
- } else {
- this._state.dragged = 0;
- }
-
- this._state.percentage[this._state.dragged] = percentage;
- this._layout();
-
- if (this.touchCapable) {
- document.removeEventListener("touchmove", this.mousemove, false);
- document.removeEventListener("touchend", this.mouseup, false);
- }
-
- if(this.mousemove){
- document.removeEventListener("mousemove", this.mousemove, false);
- }
- if(this.mouseup){
- document.removeEventListener("mouseup", this.mouseup, false);
- }
-
- this.mousemove = this._mousemove.bind(this);
- this.mouseup = this._mouseup.bind(this);
-
- if (this.touchCapable) {
- // Touch: Bind touch events:
- document.addEventListener("touchmove", this.mousemove, false);
- document.addEventListener("touchend", this.mouseup, false);
- }
- // Bind mouse events:
- document.addEventListener("mousemove", this.mousemove, false);
- document.addEventListener("mouseup", this.mouseup, false);
-
- this._state.inDrag = true;
- var newValue = this._calculateValue();
-
- this._trigger('slideStart', newValue);
-
- this._setDataVal(newValue);
- this.setValue(newValue, false, true);
-
- this._pauseEvent(ev);
-
- if (this.options.focus) {
- this._triggerFocusOnHandle(this._state.dragged);
- }
-
- return true;
- },
- _triggerFocusOnHandle: function(handleIdx) {
- if(handleIdx === 0) {
- this.handle1.focus();
- }
- if(handleIdx === 1) {
- this.handle2.focus();
- }
- },
- _keydown: function(handleIdx, ev) {
- if(!this._state.enabled) {
- return false;
- }
-
- var dir;
- switch (ev.keyCode) {
- case 37: // left
- case 40: // down
- dir = -1;
- break;
- case 39: // right
- case 38: // up
- dir = 1;
- break;
- }
- if (!dir) {
- return;
- }
-
- // use natural arrow keys instead of from min to max
- if (this.options.natural_arrow_keys) {
- var ifVerticalAndNotReversed = (this.options.orientation === 'vertical' && !this.options.reversed);
- var ifHorizontalAndReversed = (this.options.orientation === 'horizontal' && this.options.reversed);
-
- if (ifVerticalAndNotReversed || ifHorizontalAndReversed) {
- dir = -dir;
- }
- }
-
- var val = this._state.value[handleIdx] + dir * this.options.step;
- if (this.options.range) {
- val = [ (!handleIdx) ? val : this._state.value[0],
- ( handleIdx) ? val : this._state.value[1]];
- }
-
- this._trigger('slideStart', val);
- this._setDataVal(val);
- this.setValue(val, true, true);
-
- this._setDataVal(val);
- this._trigger('slideStop', val);
- this._layout();
-
- this._pauseEvent(ev);
-
- return false;
- },
- _pauseEvent: function(ev) {
- if(ev.stopPropagation) {
- ev.stopPropagation();
- }
- if(ev.preventDefault) {
- ev.preventDefault();
- }
- ev.cancelBubble=true;
- ev.returnValue=false;
- },
- _mousemove: function(ev) {
- if(!this._state.enabled) {
- return false;
- }
-
- var percentage = this._getPercentage(ev);
- this._adjustPercentageForRangeSliders(percentage);
- this._state.percentage[this._state.dragged] = percentage;
- this._layout();
-
- var val = this._calculateValue(true);
- this.setValue(val, true, true);
-
- return false;
- },
- _adjustPercentageForRangeSliders: function(percentage) {
- if (this.options.range) {
- var precision = this._getNumDigitsAfterDecimalPlace(percentage);
- precision = precision ? precision - 1 : 0;
- var percentageWithAdjustedPrecision = this._applyToFixedAndParseFloat(percentage, precision);
- if (this._state.dragged === 0 && this._applyToFixedAndParseFloat(this._state.percentage[1], precision) < percentageWithAdjustedPrecision) {
- this._state.percentage[0] = this._state.percentage[1];
- this._state.dragged = 1;
- } else if (this._state.dragged === 1 && this._applyToFixedAndParseFloat(this._state.percentage[0], precision) > percentageWithAdjustedPrecision) {
- this._state.percentage[1] = this._state.percentage[0];
- this._state.dragged = 0;
- }
- }
- },
- _mouseup: function() {
- if(!this._state.enabled) {
- return false;
- }
- if (this.touchCapable) {
- // Touch: Unbind touch event handlers:
- document.removeEventListener("touchmove", this.mousemove, false);
- document.removeEventListener("touchend", this.mouseup, false);
- }
- // Unbind mouse event handlers:
- document.removeEventListener("mousemove", this.mousemove, false);
- document.removeEventListener("mouseup", this.mouseup, false);
-
- this._state.inDrag = false;
- if (this._state.over === false) {
- this._hideTooltip();
- }
- var val = this._calculateValue(true);
-
- this._layout();
- this._setDataVal(val);
- this._trigger('slideStop', val);
-
- return false;
- },
- _calculateValue: function(snapToClosestTick) {
- var val;
- if (this.options.range) {
- val = [this.options.min,this.options.max];
- if (this._state.percentage[0] !== 0){
- val[0] = this._toValue(this._state.percentage[0]);
- val[0] = this._applyPrecision(val[0]);
- }
- if (this._state.percentage[1] !== 100){
- val[1] = this._toValue(this._state.percentage[1]);
- val[1] = this._applyPrecision(val[1]);
- }
- } else {
- val = this._toValue(this._state.percentage[0]);
- val = parseFloat(val);
- val = this._applyPrecision(val);
- }
-
- if (snapToClosestTick) {
- var min = [val, Infinity];
- for (var i = 0; i < this.options.ticks.length; i++) {
- var diff = Math.abs(this.options.ticks[i] - val);
- if (diff <= min[1]) {
- min = [this.options.ticks[i], diff];
- }
- }
- if (min[1] <= this.options.ticks_snap_bounds) {
- return min[0];
- }
- }
-
- return val;
- },
- _applyPrecision: function(val) {
- var precision = this.options.precision || this._getNumDigitsAfterDecimalPlace(this.options.step);
- return this._applyToFixedAndParseFloat(val, precision);
- },
- _getNumDigitsAfterDecimalPlace: function(num) {
- var match = (''+num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
- if (!match) { return 0; }
- return Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0));
- },
- _applyToFixedAndParseFloat: function(num, toFixedInput) {
- var truncatedNum = num.toFixed(toFixedInput);
- return parseFloat(truncatedNum);
- },
- /*
- Credits to Mike Samuel for the following method!
- Source: http://stackoverflow.com/questions/10454518/javascript-how-to-retrieve-the-number-of-decimals-of-a-string-number
- */
- _getPercentage: function(ev) {
- if (this.touchCapable && (ev.type === 'touchstart' || ev.type === 'touchmove')) {
- ev = ev.touches[0];
- }
-
- var eventPosition = ev[this.mousePos];
- var sliderOffset = this._state.offset[this.stylePos];
- var distanceToSlide = eventPosition - sliderOffset;
- // Calculate what percent of the length the slider handle has slid
- var percentage = (distanceToSlide / this._state.size) * 100;
- percentage = Math.round(percentage / this._state.percentage[2]) * this._state.percentage[2];
- if (this.options.reversed) {
- percentage = 100 - percentage;
- }
-
- // Make sure the percent is within the bounds of the slider.
- // 0% corresponds to the 'min' value of the slide
- // 100% corresponds to the 'max' value of the slide
- return Math.max(0, Math.min(100, percentage));
- },
- _validateInputValue: function(val) {
- if (typeof val === 'number') {
- return val;
- } else if (Array.isArray(val)) {
- this._validateArray(val);
- return val;
- } else {
- throw new Error( ErrorMsgs.formatInvalidInputErrorMsg(val) );
- }
- },
- _validateArray: function(val) {
- for(var i = 0; i < val.length; i++) {
- var input = val[i];
- if (typeof input !== 'number') { throw new Error( ErrorMsgs.formatInvalidInputErrorMsg(input) ); }
- }
- },
- _setDataVal: function(val) {
- this.element.setAttribute('data-value', val);
- this.element.setAttribute('value', val);
- this.element.value = val;
- },
- _trigger: function(evt, val) {
- val = (val || val === 0) ? val : undefined;
-
- var callbackFnArray = this.eventToCallbackMap[evt];
- if(callbackFnArray && callbackFnArray.length) {
- for(var i = 0; i < callbackFnArray.length; i++) {
- var callbackFn = callbackFnArray[i];
- callbackFn(val);
- }
- }
-
- /* If JQuery exists, trigger JQuery events */
- if($) {
- this._triggerJQueryEvent(evt, val);
- }
- },
- _triggerJQueryEvent: function(evt, val) {
- var eventData = {
- type: evt,
- value: val
- };
- this.$element.trigger(eventData);
- this.$sliderElem.trigger(eventData);
- },
- _unbindJQueryEventHandlers: function() {
- this.$element.off();
- this.$sliderElem.off();
- },
- _setText: function(element, text) {
- if(typeof element.innerText !== "undefined") {
- element.innerText = text;
- } else if(typeof element.textContent !== "undefined") {
- element.textContent = text;
- }
- },
- _removeClass: function(element, classString) {
- var classes = classString.split(" ");
- var newClasses = element.className;
-
- for(var i = 0; i < classes.length; i++) {
- var classTag = classes[i];
- var regex = new RegExp("(?:\\s|^)" + classTag + "(?:\\s|$)");
- newClasses = newClasses.replace(regex, " ");
- }
-
- element.className = newClasses.trim();
- },
- _addClass: function(element, classString) {
- var classes = classString.split(" ");
- var newClasses = element.className;
-
- for(var i = 0; i < classes.length; i++) {
- var classTag = classes[i];
- var regex = new RegExp("(?:\\s|^)" + classTag + "(?:\\s|$)");
- var ifClassExists = regex.test(newClasses);
-
- if(!ifClassExists) {
- newClasses += " " + classTag;
- }
- }
-
- element.className = newClasses.trim();
- },
- _offsetLeft: function(obj){
- return obj.getBoundingClientRect().left;
- },
- _offsetTop: function(obj){
- var offsetTop = obj.offsetTop;
- while((obj = obj.offsetParent) && !isNaN(obj.offsetTop)){
- offsetTop += obj.offsetTop;
- }
- return offsetTop;
- },
- _offset: function (obj) {
- return {
- left: this._offsetLeft(obj),
- top: this._offsetTop(obj)
- };
- },
- _css: function(elementRef, styleName, value) {
- if ($) {
- $.style(elementRef, styleName, value);
- } else {
- var style = styleName.replace(/^-ms-/, "ms-").replace(/-([\da-z])/gi, function (all, letter) {
- return letter.toUpperCase();
- });
- elementRef.style[style] = value;
- }
- },
- _toValue: function(percentage) {
- return this.options.scale.toValue.apply(this, [percentage]);
- },
- _toPercentage: function(value) {
- return this.options.scale.toPercentage.apply(this, [value]);
- },
- _setTooltipPosition: function(){
- var tooltips = [this.tooltip, this.tooltip_min, this.tooltip_max];
- if (this.options.orientation === 'vertical'){
- var tooltipPos = this.options.tooltip_position || 'right';
- var oppositeSide = (tooltipPos === 'left') ? 'right' : 'left';
- tooltips.forEach(function(tooltip){
- this._addClass(tooltip, tooltipPos);
- tooltip.style[oppositeSide] = '100%';
- }.bind(this));
- } else if(this.options.tooltip_position === 'bottom') {
- tooltips.forEach(function(tooltip){
- this._addClass(tooltip, 'bottom');
- tooltip.style.top = 22 + 'px';
- }.bind(this));
- } else {
- tooltips.forEach(function(tooltip){
- this._addClass(tooltip, 'top');
- tooltip.style.top = -this.tooltip.outerHeight - 14 + 'px';
- }.bind(this));
- }
- }
- };
-
- /*********************************
-
- Attach to global namespace
-
- *********************************/
- if($) {
- var namespace = $.fn.slider ? 'bootstrapSlider' : 'slider';
- $.bridget(namespace, Slider);
- }
-
- })( $ );
-
- return Slider;
-}));
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/plugins/bootstrap-slider/slider.css b/power-admin/src/main/webapp/static/bootstrap-3.3.7/plugins/bootstrap-slider/slider.css
deleted file mode 100644
index 3a64928..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/plugins/bootstrap-slider/slider.css
+++ /dev/null
@@ -1,282 +0,0 @@
-/*!
- * Slider for Bootstrap
- *
- * Copyright 2012 Stefan Petre
- * Licensed under the Apache License v2.0
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- */
-.slider {
- display: block;
- vertical-align: middle;
- position: relative;
-
-}
-.slider.slider-horizontal {
- width: 100%;
- height: 20px;
- margin-bottom: 20px;
-}
-.slider.slider-horizontal:last-of-type {
- margin-bottom: 0;
-}
-.slider.slider-horizontal .slider-track {
- height: 10px;
- width: 100%;
- margin-top: -5px;
- top: 50%;
- left: 0;
-}
-.slider.slider-horizontal .slider-selection,
-.slider.slider-horizontal .slider-track-low,
-.slider.slider-horizontal .slider-track-high {
- height: 100%;
- top: 0;
- bottom: 0;
-}
-.slider.slider-horizontal .slider-tick,
-.slider.slider-horizontal .slider-handle {
- margin-left: -10px;
- margin-top: -5px;
-}
-.slider.slider-horizontal .slider-tick.triangle,
-.slider.slider-horizontal .slider-handle.triangle {
- border-width: 0 10px 10px 10px;
- width: 0;
- height: 0;
- border-bottom-color: #0480be;
- margin-top: 0;
-}
-.slider.slider-horizontal .slider-tick-label-container {
- white-space: nowrap;
- margin-top: 20px;
-}
-.slider.slider-horizontal .slider-tick-label-container .slider-tick-label {
- padding-top: 4px;
- display: inline-block;
- text-align: center;
-}
-.slider.slider-vertical {
- height: 230px;
- width: 20px;
- margin-right: 20px;
- display: inline-block;
-}
-.slider.slider-vertical:last-of-type {
- margin-right: 0;
-}
-.slider.slider-vertical .slider-track {
- width: 10px;
- height: 100%;
- margin-left: -5px;
- left: 50%;
- top: 0;
-}
-.slider.slider-vertical .slider-selection {
- width: 100%;
- left: 0;
- top: 0;
- bottom: 0;
-}
-.slider.slider-vertical .slider-track-low,
-.slider.slider-vertical .slider-track-high {
- width: 100%;
- left: 0;
- right: 0;
-}
-.slider.slider-vertical .slider-tick,
-.slider.slider-vertical .slider-handle {
- margin-left: -5px;
- margin-top: -10px;
-}
-.slider.slider-vertical .slider-tick.triangle,
-.slider.slider-vertical .slider-handle.triangle {
- border-width: 10px 0 10px 10px;
- width: 1px;
- height: 1px;
- border-left-color: #0480be;
- margin-left: 0;
-}
-.slider.slider-vertical .slider-tick-label-container {
- white-space: nowrap;
-}
-.slider.slider-vertical .slider-tick-label-container .slider-tick-label {
- padding-left: 4px;
-}
-.slider.slider-disabled .slider-handle {
- background-image: -webkit-linear-gradient(top, #dfdfdf 0%, #bebebe 100%);
- background-image: -o-linear-gradient(top, #dfdfdf 0%, #bebebe 100%);
- background-image: linear-gradient(to bottom, #dfdfdf 0%, #bebebe 100%);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdfdfdf', endColorstr='#ffbebebe', GradientType=0);
-}
-.slider.slider-disabled .slider-track {
- background-image: -webkit-linear-gradient(top, #e5e5e5 0%, #e9e9e9 100%);
- background-image: -o-linear-gradient(top, #e5e5e5 0%, #e9e9e9 100%);
- background-image: linear-gradient(to bottom, #e5e5e5 0%, #e9e9e9 100%);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe5e5e5', endColorstr='#ffe9e9e9', GradientType=0);
- cursor: not-allowed;
-}
-.slider input {
- display: none;
-}
-.slider .tooltip.top {
- margin-top: -36px;
-}
-.slider .tooltip-inner {
- white-space: nowrap;
-}
-.slider .hide {
- display: none;
-}
-.slider-track {
- position: absolute;
- cursor: pointer;
- background-color: #f7f7f7;
- background-image: -moz-linear-gradient(top, #f0f0f0, #f9f9f9);
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f0f0f0), to(#f9f9f9));
- background-image: -webkit-linear-gradient(top, #f0f0f0, #f9f9f9);
- background-image: -o-linear-gradient(top, #f0f0f0, #f9f9f9);
- background-image: linear-gradient(to bottom, #f0f0f0, #f9f9f9);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0f0f0', endColorstr='#fff9f9f9', GradientType=0);
- -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
- -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
- box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
-}
-.slider-selection {
- position: absolute;
- background-color: #f7f7f7;
- background-image: -moz-linear-gradient(top, #f9f9f9, #f5f5f5);
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f9f9f9), to(#f5f5f5));
- background-image: -webkit-linear-gradient(top, #f9f9f9, #f5f5f5);
- background-image: -o-linear-gradient(top, #f9f9f9, #f5f5f5);
- background-image: linear-gradient(to bottom, #f9f9f9, #f5f5f5);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9', endColorstr='#fff5f5f5', GradientType=0);
- -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
- -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
- box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
-}
-.slider-selection.tick-slider-selection {
- background-image: -webkit-linear-gradient(top, #89cdef 0%, #81bfde 100%);
- background-image: -o-linear-gradient(top, #89cdef 0%, #81bfde 100%);
- background-image: linear-gradient(to bottom, #89cdef 0%, #81bfde 100%);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff89cdef', endColorstr='#ff81bfde', GradientType=0);
-}
-.slider-track-low,
-.slider-track-high {
- position: absolute;
- background: transparent;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- border-radius: 4px;
-}
-.slider-handle {
- position: absolute;
- width: 20px;
- height: 20px;
- background-color: #444;
- -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
- -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
- box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
- opacity: 1;
- border: 0px solid transparent;
-}
-.slider-handle.round {
- -webkit-border-radius: 20px;
- -moz-border-radius: 20px;
- border-radius: 20px;
-}
-.slider-handle.triangle {
- background: transparent none;
-}
-.slider-handle.custom {
- background: transparent none;
-}
-.slider-handle.custom::before {
- line-height: 20px;
- font-size: 20px;
- content: '\2605';
- color: #726204;
-}
-.slider-tick {
- position: absolute;
- width: 20px;
- height: 20px;
- background-image: -webkit-linear-gradient(top, #f9f9f9 0%, #f5f5f5 100%);
- background-image: -o-linear-gradient(top, #f9f9f9 0%, #f5f5f5 100%);
- background-image: linear-gradient(to bottom, #f9f9f9 0%, #f5f5f5 100%);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9', endColorstr='#fff5f5f5', GradientType=0);
- -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
- box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- filter: none;
- opacity: 0.8;
- border: 0px solid transparent;
-}
-.slider-tick.round {
- border-radius: 50%;
-}
-.slider-tick.triangle {
- background: transparent none;
-}
-.slider-tick.custom {
- background: transparent none;
-}
-.slider-tick.custom::before {
- line-height: 20px;
- font-size: 20px;
- content: '\2605';
- color: #726204;
-}
-.slider-tick.in-selection {
- background-image: -webkit-linear-gradient(top, #89cdef 0%, #81bfde 100%);
- background-image: -o-linear-gradient(top, #89cdef 0%, #81bfde 100%);
- background-image: linear-gradient(to bottom, #89cdef 0%, #81bfde 100%);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff89cdef', endColorstr='#ff81bfde', GradientType=0);
- opacity: 1;
-}
-.slider-disabled .slider-selection {
- opacity: 0.5;
-}
-
-#red .slider-selection {
- background: #f56954;
-}
-
-#blue .slider-selection {
- background: #3c8dbc;
-}
-
-#green .slider-selection {
- background: #00a65a;
-}
-
-#yellow .slider-selection {
- background: #f39c12;
-}
-
-#aqua .slider-selection {
- background: #00c0ef;
-}
-
-#purple .slider-selection {
- background: #932ab6;
-}
\ No newline at end of file
diff --git a/power-admin/src/main/webapp/static/bootstrap-3.3.7/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.js b/power-admin/src/main/webapp/static/bootstrap-3.3.7/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.js
deleted file mode 100644
index acccf91..0000000
--- a/power-admin/src/main/webapp/static/bootstrap-3.3.7/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.js
+++ /dev/null
@@ -1,14975 +0,0 @@
-// TODO: in future try to replace most inline compability checks with polyfills for code readability
-
-// element.textContent polyfill.
-// Unsupporting browsers: IE8
-
-if (Object.defineProperty && Object.getOwnPropertyDescriptor && Object.getOwnPropertyDescriptor(Element.prototype, "textContent") && !Object.getOwnPropertyDescriptor(Element.prototype, "textContent").get) {
- (function() {
- var innerText = Object.getOwnPropertyDescriptor(Element.prototype, "innerText");
- Object.defineProperty(Element.prototype, "textContent",
- {
- get: function() {
- return innerText.get.call(this);
- },
- set: function(s) {
- return innerText.set.call(this, s);
- }
- }
- );
- })();
-}
-
-// isArray polyfill for ie8
-if(!Array.isArray) {
- Array.isArray = function(arg) {
- return Object.prototype.toString.call(arg) === '[object Array]';
- };
-};/**
- * @license wysihtml5x v0.4.15
- * https://github.com/Edicy/wysihtml5
- *
- * Author: Christopher Blum (https://github.com/tiff)
- * Secondary author of extended features: Oliver Pulges (https://github.com/pulges)
- *
- * Copyright (C) 2012 XING AG
- * Licensed under the MIT license (MIT)
- *
- */
-var wysihtml5 = {
- version: "0.4.15",
-
- // namespaces
- commands: {},
- dom: {},
- quirks: {},
- toolbar: {},
- lang: {},
- selection: {},
- views: {},
-
- INVISIBLE_SPACE: "\uFEFF",
-
- EMPTY_FUNCTION: function() {},
-
- ELEMENT_NODE: 1,
- TEXT_NODE: 3,
-
- BACKSPACE_KEY: 8,
- ENTER_KEY: 13,
- ESCAPE_KEY: 27,
- SPACE_KEY: 32,
- DELETE_KEY: 46
-};
-;/**
- * Rangy, a cross-browser JavaScript range and selection library
- * http://code.google.com/p/rangy/
- *
- * Copyright 2014, Tim Down
- * Licensed under the MIT license.
- * Version: 1.3alpha.20140804
- * Build date: 4 August 2014
- */
-
-(function(factory, global) {
- if (typeof define == "function" && define.amd) {
- // AMD. Register as an anonymous module.
- define(factory);
-/*
- TODO: look into this properly.
-
- } else if (typeof exports == "object") {
- // Node/CommonJS style for Browserify
- module.exports = factory;
-*/
- } else {
- // No AMD or CommonJS support so we place Rangy in a global variable
- global.rangy = factory();
- }
-})(function() {
-
- var OBJECT = "object", FUNCTION = "function", UNDEFINED = "undefined";
-
- // Minimal set of properties required for DOM Level 2 Range compliance. Comparison constants such as START_TO_START
- // are omitted because ranges in KHTML do not have them but otherwise work perfectly well. See issue 113.
- var domRangeProperties = ["startContainer", "startOffset", "endContainer", "endOffset", "collapsed",
- "commonAncestorContainer"];
-
- // Minimal set of methods required for DOM Level 2 Range compliance
- var domRangeMethods = ["setStart", "setStartBefore", "setStartAfter", "setEnd", "setEndBefore",
- "setEndAfter", "collapse", "selectNode", "selectNodeContents", "compareBoundaryPoints", "deleteContents",
- "extractContents", "cloneContents", "insertNode", "surroundContents", "cloneRange", "toString", "detach"];
-
- var textRangeProperties = ["boundingHeight", "boundingLeft", "boundingTop", "boundingWidth", "htmlText", "text"];
-
- // Subset of TextRange's full set of methods that we're interested in
- var textRangeMethods = ["collapse", "compareEndPoints", "duplicate", "moveToElementText", "parentElement", "select",
- "setEndPoint", "getBoundingClientRect"];
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- // Trio of functions taken from Peter Michaux's article:
- // http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
- function isHostMethod(o, p) {
- var t = typeof o[p];
- return t == FUNCTION || (!!(t == OBJECT && o[p])) || t == "unknown";
- }
-
- function isHostObject(o, p) {
- return !!(typeof o[p] == OBJECT && o[p]);
- }
-
- function isHostProperty(o, p) {
- return typeof o[p] != UNDEFINED;
- }
-
- // Creates a convenience function to save verbose repeated calls to tests functions
- function createMultiplePropertyTest(testFunc) {
- return function(o, props) {
- var i = props.length;
- while (i--) {
- if (!testFunc(o, props[i])) {
- return false;
- }
- }
- return true;
- };
- }
-
- // Next trio of functions are a convenience to save verbose repeated calls to previous two functions
- var areHostMethods = createMultiplePropertyTest(isHostMethod);
- var areHostObjects = createMultiplePropertyTest(isHostObject);
- var areHostProperties = createMultiplePropertyTest(isHostProperty);
-
- function isTextRange(range) {
- return range && areHostMethods(range, textRangeMethods) && areHostProperties(range, textRangeProperties);
- }
-
- function getBody(doc) {
- return isHostObject(doc, "body") ? doc.body : doc.getElementsByTagName("body")[0];
- }
-
- var modules = {};
-
- var api = {
- version: "1.3alpha.20140804",
- initialized: false,
- supported: true,
-
- util: {
- isHostMethod: isHostMethod,
- isHostObject: isHostObject,
- isHostProperty: isHostProperty,
- areHostMethods: areHostMethods,
- areHostObjects: areHostObjects,
- areHostProperties: areHostProperties,
- isTextRange: isTextRange,
- getBody: getBody
- },
-
- features: {},
-
- modules: modules,
- config: {
- alertOnFail: true,
- alertOnWarn: false,
- preferTextRange: false,
- autoInitialize: (typeof rangyAutoInitialize == UNDEFINED) ? true : rangyAutoInitialize
- }
- };
-
- function consoleLog(msg) {
- if (isHostObject(window, "console") && isHostMethod(window.console, "log")) {
- window.console.log(msg);
- }
- }
-
- function alertOrLog(msg, shouldAlert) {
- if (shouldAlert) {
- window.alert(msg);
- } else {
- consoleLog(msg);
- }
- }
-
- function fail(reason) {
- api.initialized = true;
- api.supported = false;
- alertOrLog("Rangy is not supported on this page in your browser. Reason: " + reason, api.config.alertOnFail);
- }
-
- api.fail = fail;
-
- function warn(msg) {
- alertOrLog("Rangy warning: " + msg, api.config.alertOnWarn);
- }
-
- api.warn = warn;
-
- // Add utility extend() method
- if ({}.hasOwnProperty) {
- api.util.extend = function(obj, props, deep) {
- var o, p;
- for (var i in props) {
- if (props.hasOwnProperty(i)) {
- o = obj[i];
- p = props[i];
- if (deep && o !== null && typeof o == "object" && p !== null && typeof p == "object") {
- api.util.extend(o, p, true);
- }
- obj[i] = p;
- }
- }
- // Special case for toString, which does not show up in for...in loops in IE <= 8
- if (props.hasOwnProperty("toString")) {
- obj.toString = props.toString;
- }
- return obj;
- };
- } else {
- fail("hasOwnProperty not supported");
- }
-
- // Test whether Array.prototype.slice can be relied on for NodeLists and use an alternative toArray() if not
- (function() {
- var el = document.createElement("div");
- el.appendChild(document.createElement("span"));
- var slice = [].slice;
- var toArray;
- try {
- if (slice.call(el.childNodes, 0)[0].nodeType == 1) {
- toArray = function(arrayLike) {
- return slice.call(arrayLike, 0);
- };
- }
- } catch (e) {}
-
- if (!toArray) {
- toArray = function(arrayLike) {
- var arr = [];
- for (var i = 0, len = arrayLike.length; i < len; ++i) {
- arr[i] = arrayLike[i];
- }
- return arr;
- };
- }
-
- api.util.toArray = toArray;
- })();
-
-
- // Very simple event handler wrapper function that doesn't attempt to solve issues such as "this" handling or
- // normalization of event properties
- var addListener;
- if (isHostMethod(document, "addEventListener")) {
- addListener = function(obj, eventType, listener) {
- obj.addEventListener(eventType, listener, false);
- };
- } else if (isHostMethod(document, "attachEvent")) {
- addListener = function(obj, eventType, listener) {
- obj.attachEvent("on" + eventType, listener);
- };
- } else {
- fail("Document does not have required addEventListener or attachEvent method");
- }
-
- api.util.addListener = addListener;
-
- var initListeners = [];
-
- function getErrorDesc(ex) {
- return ex.message || ex.description || String(ex);
- }
-
- // Initialization
- function init() {
- if (api.initialized) {
- return;
- }
- var testRange;
- var implementsDomRange = false, implementsTextRange = false;
-
- // First, perform basic feature tests
-
- if (isHostMethod(document, "createRange")) {
- testRange = document.createRange();
- if (areHostMethods(testRange, domRangeMethods) && areHostProperties(testRange, domRangeProperties)) {
- implementsDomRange = true;
- }
- }
-
- var body = getBody(document);
- if (!body || body.nodeName.toLowerCase() != "body") {
- fail("No body element found");
- return;
- }
-
- if (body && isHostMethod(body, "createTextRange")) {
- testRange = body.createTextRange();
- if (isTextRange(testRange)) {
- implementsTextRange = true;
- }
- }
-
- if (!implementsDomRange && !implementsTextRange) {
- fail("Neither Range nor TextRange are available");
- return;
- }
-
- api.initialized = true;
- api.features = {
- implementsDomRange: implementsDomRange,
- implementsTextRange: implementsTextRange
- };
-
- // Initialize modules
- var module, errorMessage;
- for (var moduleName in modules) {
- if ( (module = modules[moduleName]) instanceof Module ) {
- module.init(module, api);
- }
- }
-
- // Call init listeners
- for (var i = 0, len = initListeners.length; i < len; ++i) {
- try {
- initListeners[i](api);
- } catch (ex) {
- errorMessage = "Rangy init listener threw an exception. Continuing. Detail: " + getErrorDesc(ex);
- consoleLog(errorMessage);
- }
- }
- }
-
- // Allow external scripts to initialize this library in case it's loaded after the document has loaded
- api.init = init;
-
- // Execute listener immediately if already initialized
- api.addInitListener = function(listener) {
- if (api.initialized) {
- listener(api);
- } else {
- initListeners.push(listener);
- }
- };
-
- var shimListeners = [];
-
- api.addShimListener = function(listener) {
- shimListeners.push(listener);
- };
-
- function shim(win) {
- win = win || window;
- init();
-
- // Notify listeners
- for (var i = 0, len = shimListeners.length; i < len; ++i) {
- shimListeners[i](win);
- }
- }
-
- api.shim = api.createMissingNativeApi = shim;
-
- function Module(name, dependencies, initializer) {
- this.name = name;
- this.dependencies = dependencies;
- this.initialized = false;
- this.supported = false;
- this.initializer = initializer;
- }
-
- Module.prototype = {
- init: function() {
- var requiredModuleNames = this.dependencies || [];
- for (var i = 0, len = requiredModuleNames.length, requiredModule, moduleName; i < len; ++i) {
- moduleName = requiredModuleNames[i];
-
- requiredModule = modules[moduleName];
- if (!requiredModule || !(requiredModule instanceof Module)) {
- throw new Error("required module '" + moduleName + "' not found");
- }
-
- requiredModule.init();
-
- if (!requiredModule.supported) {
- throw new Error("required module '" + moduleName + "' not supported");
- }
- }
-
- // Now run initializer
- this.initializer(this);
- },
-
- fail: function(reason) {
- this.initialized = true;
- this.supported = false;
- throw new Error("Module '" + this.name + "' failed to load: " + reason);
- },
-
- warn: function(msg) {
- api.warn("Module " + this.name + ": " + msg);
- },
-
- deprecationNotice: function(deprecated, replacement) {
- api.warn("DEPRECATED: " + deprecated + " in module " + this.name + "is deprecated. Please use " +
- replacement + " instead");
- },
-
- createError: function(msg) {
- return new Error("Error in Rangy " + this.name + " module: " + msg);
- }
- };
-
- function createModule(isCore, name, dependencies, initFunc) {
- var newModule = new Module(name, dependencies, function(module) {
- if (!module.initialized) {
- module.initialized = true;
- try {
- initFunc(api, module);
- module.supported = true;
- } catch (ex) {
- var errorMessage = "Module '" + name + "' failed to load: " + getErrorDesc(ex);
- consoleLog(errorMessage);
- }
- }
- });
- modules[name] = newModule;
- }
-
- api.createModule = function(name) {
- // Allow 2 or 3 arguments (second argument is an optional array of dependencies)
- var initFunc, dependencies;
- if (arguments.length == 2) {
- initFunc = arguments[1];
- dependencies = [];
- } else {
- initFunc = arguments[2];
- dependencies = arguments[1];
- }
-
- var module = createModule(false, name, dependencies, initFunc);
-
- // Initialize the module immediately if the core is already initialized
- if (api.initialized) {
- module.init();
- }
- };
-
- api.createCoreModule = function(name, dependencies, initFunc) {
- createModule(true, name, dependencies, initFunc);
- };
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- // Ensure rangy.rangePrototype and rangy.selectionPrototype are available immediately
-
- function RangePrototype() {}
- api.RangePrototype = RangePrototype;
- api.rangePrototype = new RangePrototype();
-
- function SelectionPrototype() {}
- api.selectionPrototype = new SelectionPrototype();
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- // Wait for document to load before running tests
-
- var docReady = false;
-
- var loadHandler = function(e) {
- if (!docReady) {
- docReady = true;
- if (!api.initialized && api.config.autoInitialize) {
- init();
- }
- }
- };
-
- // Test whether we have window and document objects that we will need
- if (typeof window == UNDEFINED) {
- fail("No window found");
- return;
- }
- if (typeof document == UNDEFINED) {
- fail("No document found");
- return;
- }
-
- if (isHostMethod(document, "addEventListener")) {
- document.addEventListener("DOMContentLoaded", loadHandler, false);
- }
-
- // Add a fallback in case the DOMContentLoaded event isn't supported
- addListener(window, "load", loadHandler);
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- // DOM utility methods used by Rangy
- api.createCoreModule("DomUtil", [], function(api, module) {
- var UNDEF = "undefined";
- var util = api.util;
-
- // Perform feature tests
- if (!util.areHostMethods(document, ["createDocumentFragment", "createElement", "createTextNode"])) {
- module.fail("document missing a Node creation method");
- }
-
- if (!util.isHostMethod(document, "getElementsByTagName")) {
- module.fail("document missing getElementsByTagName method");
- }
-
- var el = document.createElement("div");
- if (!util.areHostMethods(el, ["insertBefore", "appendChild", "cloneNode"] ||
- !util.areHostObjects(el, ["previousSibling", "nextSibling", "childNodes", "parentNode"]))) {
- module.fail("Incomplete Element implementation");
- }
-
- // innerHTML is required for Range's createContextualFragment method
- if (!util.isHostProperty(el, "innerHTML")) {
- module.fail("Element is missing innerHTML property");
- }
-
- var textNode = document.createTextNode("test");
- if (!util.areHostMethods(textNode, ["splitText", "deleteData", "insertData", "appendData", "cloneNode"] ||
- !util.areHostObjects(el, ["previousSibling", "nextSibling", "childNodes", "parentNode"]) ||
- !util.areHostProperties(textNode, ["data"]))) {
- module.fail("Incomplete Text Node implementation");
- }
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- // Removed use of indexOf because of a bizarre bug in Opera that is thrown in one of the Acid3 tests. I haven't been
- // able to replicate it outside of the test. The bug is that indexOf returns -1 when called on an Array that
- // contains just the document as a single element and the value searched for is the document.
- var arrayContains = /*Array.prototype.indexOf ?
- function(arr, val) {
- return arr.indexOf(val) > -1;
- }:*/
-
- function(arr, val) {
- var i = arr.length;
- while (i--) {
- if (arr[i] === val) {
- return true;
- }
- }
- return false;
- };
-
- // Opera 11 puts HTML elements in the null namespace, it seems, and IE 7 has undefined namespaceURI
- function isHtmlNamespace(node) {
- var ns;
- return typeof node.namespaceURI == UNDEF || ((ns = node.namespaceURI) === null || ns == "http://www.w3.org/1999/xhtml");
- }
-
- function parentElement(node) {
- var parent = node.parentNode;
- return (parent.nodeType == 1) ? parent : null;
- }
-
- function getNodeIndex(node) {
- var i = 0;
- while( (node = node.previousSibling) ) {
- ++i;
- }
- return i;
- }
-
- function getNodeLength(node) {
- switch (node.nodeType) {
- case 7:
- case 10:
- return 0;
- case 3:
- case 8:
- return node.length;
- default:
- return node.childNodes.length;
- }
- }
-
- function getCommonAncestor(node1, node2) {
- var ancestors = [], n;
- for (n = node1; n; n = n.parentNode) {
- ancestors.push(n);
- }
-
- for (n = node2; n; n = n.parentNode) {
- if (arrayContains(ancestors, n)) {
- return n;
- }
- }
-
- return null;
- }
-
- function isAncestorOf(ancestor, descendant, selfIsAncestor) {
- var n = selfIsAncestor ? descendant : descendant.parentNode;
- while (n) {
- if (n === ancestor) {
- return true;
- } else {
- n = n.parentNode;
- }
- }
- return false;
- }
-
- function isOrIsAncestorOf(ancestor, descendant) {
- return isAncestorOf(ancestor, descendant, true);
- }
-
- function getClosestAncestorIn(node, ancestor, selfIsAncestor) {
- var p, n = selfIsAncestor ? node : node.parentNode;
- while (n) {
- p = n.parentNode;
- if (p === ancestor) {
- return n;
- }
- n = p;
- }
- return null;
- }
-
- function isCharacterDataNode(node) {
- var t = node.nodeType;
- return t == 3 || t == 4 || t == 8 ; // Text, CDataSection or Comment
- }
-
- function isTextOrCommentNode(node) {
- if (!node) {
- return false;
- }
- var t = node.nodeType;
- return t == 3 || t == 8 ; // Text or Comment
- }
-
- function insertAfter(node, precedingNode) {
- var nextNode = precedingNode.nextSibling, parent = precedingNode.parentNode;
- if (nextNode) {
- parent.insertBefore(node, nextNode);
- } else {
- parent.appendChild(node);
- }
- return node;
- }
-
- // Note that we cannot use splitText() because it is bugridden in IE 9.
- function splitDataNode(node, index, positionsToPreserve) {
- var newNode = node.cloneNode(false);
- newNode.deleteData(0, index);
- node.deleteData(index, node.length - index);
- insertAfter(newNode, node);
-
- // Preserve positions
- if (positionsToPreserve) {
- for (var i = 0, position; position = positionsToPreserve[i++]; ) {
- // Handle case where position was inside the portion of node after the split point
- if (position.node == node && position.offset > index) {
- position.node = newNode;
- position.offset -= index;
- }
- // Handle the case where the position is a node offset within node's parent
- else if (position.node == node.parentNode && position.offset > getNodeIndex(node)) {
- ++position.offset;
- }
- }
- }
- return newNode;
- }
-
- function getDocument(node) {
- if (node.nodeType == 9) {
- return node;
- } else if (typeof node.ownerDocument != UNDEF) {
- return node.ownerDocument;
- } else if (typeof node.document != UNDEF) {
- return node.document;
- } else if (node.parentNode) {
- return getDocument(node.parentNode);
- } else {
- throw module.createError("getDocument: no document found for node");
- }
- }
-
- function getWindow(node) {
- var doc = getDocument(node);
- if (typeof doc.defaultView != UNDEF) {
- return doc.defaultView;
- } else if (typeof doc.parentWindow != UNDEF) {
- return doc.parentWindow;
- } else {
- throw module.createError("Cannot get a window object for node");
- }
- }
-
- function getIframeDocument(iframeEl) {
- if (typeof iframeEl.contentDocument != UNDEF) {
- return iframeEl.contentDocument;
- } else if (typeof iframeEl.contentWindow != UNDEF) {
- return iframeEl.contentWindow.document;
- } else {
- throw module.createError("getIframeDocument: No Document object found for iframe element");
- }
- }
-
- function getIframeWindow(iframeEl) {
- if (typeof iframeEl.contentWindow != UNDEF) {
- return iframeEl.contentWindow;
- } else if (typeof iframeEl.contentDocument != UNDEF) {
- return iframeEl.contentDocument.defaultView;
- } else {
- throw module.createError("getIframeWindow: No Window object found for iframe element");
- }
- }
-
- // This looks bad. Is it worth it?
- function isWindow(obj) {
- return obj && util.isHostMethod(obj, "setTimeout") && util.isHostObject(obj, "document");
- }
-
- function getContentDocument(obj, module, methodName) {
- var doc;
-
- if (!obj) {
- doc = document;
- }
-
- // Test if a DOM node has been passed and obtain a document object for it if so
- else if (util.isHostProperty(obj, "nodeType")) {
- doc = (obj.nodeType == 1 && obj.tagName.toLowerCase() == "iframe") ?
- getIframeDocument(obj) : getDocument(obj);
- }
-
- // Test if the doc parameter appears to be a Window object
- else if (isWindow(obj)) {
- doc = obj.document;
- }
-
- if (!doc) {
- throw module.createError(methodName + "(): Parameter must be a Window object or DOM node");
- }
-
- return doc;
- }
-
- function getRootContainer(node) {
- var parent;
- while ( (parent = node.parentNode) ) {
- node = parent;
- }
- return node;
- }
-
- function comparePoints(nodeA, offsetA, nodeB, offsetB) {
- // See http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Comparing
- var nodeC, root, childA, childB, n;
- if (nodeA == nodeB) {
- // Case 1: nodes are the same
- return offsetA === offsetB ? 0 : (offsetA < offsetB) ? -1 : 1;
- } else if ( (nodeC = getClosestAncestorIn(nodeB, nodeA, true)) ) {
- // Case 2: node C (container B or an ancestor) is a child node of A
- return offsetA <= getNodeIndex(nodeC) ? -1 : 1;
- } else if ( (nodeC = getClosestAncestorIn(nodeA, nodeB, true)) ) {
- // Case 3: node C (container A or an ancestor) is a child node of B
- return getNodeIndex(nodeC) < offsetB ? -1 : 1;
- } else {
- root = getCommonAncestor(nodeA, nodeB);
- if (!root) {
- throw new Error("comparePoints error: nodes have no common ancestor");
- }
-
- // Case 4: containers are siblings or descendants of siblings
- childA = (nodeA === root) ? root : getClosestAncestorIn(nodeA, root, true);
- childB = (nodeB === root) ? root : getClosestAncestorIn(nodeB, root, true);
-
- if (childA === childB) {
- // This shouldn't be possible
- throw module.createError("comparePoints got to case 4 and childA and childB are the same!");
- } else {
- n = root.firstChild;
- while (n) {
- if (n === childA) {
- return -1;
- } else if (n === childB) {
- return 1;
- }
- n = n.nextSibling;
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- // Test for IE's crash (IE 6/7) or exception (IE >= 8) when a reference to garbage-collected text node is queried
- var crashyTextNodes = false;
-
- function isBrokenNode(node) {
- var n;
- try {
- n = node.parentNode;
- return false;
- } catch (e) {
- return true;
- }
- }
-
- (function() {
- var el = document.createElement("b");
- el.innerHTML = "1";
- var textNode = el.firstChild;
- el.innerHTML = "
";
- crashyTextNodes = isBrokenNode(textNode);
-
- api.features.crashyTextNodes = crashyTextNodes;
- })();
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- function inspectNode(node) {
- if (!node) {
- return "[No node]";
- }
- if (crashyTextNodes && isBrokenNode(node)) {
- return "[Broken node]";
- }
- if (isCharacterDataNode(node)) {
- return '"' + node.data + '"';
- }
- if (node.nodeType == 1) {
- var idAttr = node.id ? ' id="' + node.id + '"' : "";
- return "<" + node.nodeName + idAttr + ">[index:" + getNodeIndex(node) + ",length:" + node.childNodes.length + "][" + (node.innerHTML || "[innerHTML not supported]").slice(0, 25) + "]";
- }
- return node.nodeName;
- }
-
- function fragmentFromNodeChildren(node) {
- var fragment = getDocument(node).createDocumentFragment(), child;
- while ( (child = node.firstChild) ) {
- fragment.appendChild(child);
- }
- return fragment;
- }
-
- var getComputedStyleProperty;
- if (typeof window.getComputedStyle != UNDEF) {
- getComputedStyleProperty = function(el, propName) {
- return getWindow(el).getComputedStyle(el, null)[propName];
- };
- } else if (typeof document.documentElement.currentStyle != UNDEF) {
- getComputedStyleProperty = function(el, propName) {
- return el.currentStyle[propName];
- };
- } else {
- module.fail("No means of obtaining computed style properties found");
- }
-
- function NodeIterator(root) {
- this.root = root;
- this._next = root;
- }
-
- NodeIterator.prototype = {
- _current: null,
-
- hasNext: function() {
- return !!this._next;
- },
-
- next: function() {
- var n = this._current = this._next;
- var child, next;
- if (this._current) {
- child = n.firstChild;
- if (child) {
- this._next = child;
- } else {
- next = null;
- while ((n !== this.root) && !(next = n.nextSibling)) {
- n = n.parentNode;
- }
- this._next = next;
- }
- }
- return this._current;
- },
-
- detach: function() {
- this._current = this._next = this.root = null;
- }
- };
-
- function createIterator(root) {
- return new NodeIterator(root);
- }
-
- function DomPosition(node, offset) {
- this.node = node;
- this.offset = offset;
- }
-
- DomPosition.prototype = {
- equals: function(pos) {
- return !!pos && this.node === pos.node && this.offset == pos.offset;
- },
-
- inspect: function() {
- return "[DomPosition(" + inspectNode(this.node) + ":" + this.offset + ")]";
- },
-
- toString: function() {
- return this.inspect();
- }
- };
-
- function DOMException(codeName) {
- this.code = this[codeName];
- this.codeName = codeName;
- this.message = "DOMException: " + this.codeName;
- }
-
- DOMException.prototype = {
- INDEX_SIZE_ERR: 1,
- HIERARCHY_REQUEST_ERR: 3,
- WRONG_DOCUMENT_ERR: 4,
- NO_MODIFICATION_ALLOWED_ERR: 7,
- NOT_FOUND_ERR: 8,
- NOT_SUPPORTED_ERR: 9,
- INVALID_STATE_ERR: 11,
- INVALID_NODE_TYPE_ERR: 24
- };
-
- DOMException.prototype.toString = function() {
- return this.message;
- };
-
- api.dom = {
- arrayContains: arrayContains,
- isHtmlNamespace: isHtmlNamespace,
- parentElement: parentElement,
- getNodeIndex: getNodeIndex,
- getNodeLength: getNodeLength,
- getCommonAncestor: getCommonAncestor,
- isAncestorOf: isAncestorOf,
- isOrIsAncestorOf: isOrIsAncestorOf,
- getClosestAncestorIn: getClosestAncestorIn,
- isCharacterDataNode: isCharacterDataNode,
- isTextOrCommentNode: isTextOrCommentNode,
- insertAfter: insertAfter,
- splitDataNode: splitDataNode,
- getDocument: getDocument,
- getWindow: getWindow,
- getIframeWindow: getIframeWindow,
- getIframeDocument: getIframeDocument,
- getBody: util.getBody,
- isWindow: isWindow,
- getContentDocument: getContentDocument,
- getRootContainer: getRootContainer,
- comparePoints: comparePoints,
- isBrokenNode: isBrokenNode,
- inspectNode: inspectNode,
- getComputedStyleProperty: getComputedStyleProperty,
- fragmentFromNodeChildren: fragmentFromNodeChildren,
- createIterator: createIterator,
- DomPosition: DomPosition
- };
-
- api.DOMException = DOMException;
- });
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- // Pure JavaScript implementation of DOM Range
- api.createCoreModule("DomRange", ["DomUtil"], function(api, module) {
- var dom = api.dom;
- var util = api.util;
- var DomPosition = dom.DomPosition;
- var DOMException = api.DOMException;
-
- var isCharacterDataNode = dom.isCharacterDataNode;
- var getNodeIndex = dom.getNodeIndex;
- var isOrIsAncestorOf = dom.isOrIsAncestorOf;
- var getDocument = dom.getDocument;
- var comparePoints = dom.comparePoints;
- var splitDataNode = dom.splitDataNode;
- var getClosestAncestorIn = dom.getClosestAncestorIn;
- var getNodeLength = dom.getNodeLength;
- var arrayContains = dom.arrayContains;
- var getRootContainer = dom.getRootContainer;
- var crashyTextNodes = api.features.crashyTextNodes;
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- // Utility functions
-
- function isNonTextPartiallySelected(node, range) {
- return (node.nodeType != 3) &&
- (isOrIsAncestorOf(node, range.startContainer) || isOrIsAncestorOf(node, range.endContainer));
- }
-
- function getRangeDocument(range) {
- return range.document || getDocument(range.startContainer);
- }
-
- function getBoundaryBeforeNode(node) {
- return new DomPosition(node.parentNode, getNodeIndex(node));
- }
-
- function getBoundaryAfterNode(node) {
- return new DomPosition(node.parentNode, getNodeIndex(node) + 1);
- }
-
- function insertNodeAtPosition(node, n, o) {
- var firstNodeInserted = node.nodeType == 11 ? node.firstChild : node;
- if (isCharacterDataNode(n)) {
- if (o == n.length) {
- dom.insertAfter(node, n);
- } else {
- n.parentNode.insertBefore(node, o == 0 ? n : splitDataNode(n, o));
- }
- } else if (o >= n.childNodes.length) {
- n.appendChild(node);
- } else {
- n.insertBefore(node, n.childNodes[o]);
- }
- return firstNodeInserted;
- }
-
- function rangesIntersect(rangeA, rangeB, touchingIsIntersecting) {
- assertRangeValid(rangeA);
- assertRangeValid(rangeB);
-
- if (getRangeDocument(rangeB) != getRangeDocument(rangeA)) {
- throw new DOMException("WRONG_DOCUMENT_ERR");
- }
-
- var startComparison = comparePoints(rangeA.startContainer, rangeA.startOffset, rangeB.endContainer, rangeB.endOffset),
- endComparison = comparePoints(rangeA.endContainer, rangeA.endOffset, rangeB.startContainer, rangeB.startOffset);
-
- return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0;
- }
-
- function cloneSubtree(iterator) {
- var partiallySelected;
- for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) {
- partiallySelected = iterator.isPartiallySelectedSubtree();
- node = node.cloneNode(!partiallySelected);
- if (partiallySelected) {
- subIterator = iterator.getSubtreeIterator();
- node.appendChild(cloneSubtree(subIterator));
- subIterator.detach();
- }
-
- if (node.nodeType == 10) { // DocumentType
- throw new DOMException("HIERARCHY_REQUEST_ERR");
- }
- frag.appendChild(node);
- }
- return frag;
- }
-
- function iterateSubtree(rangeIterator, func, iteratorState) {
- var it, n;
- iteratorState = iteratorState || { stop: false };
- for (var node, subRangeIterator; node = rangeIterator.next(); ) {
- if (rangeIterator.isPartiallySelectedSubtree()) {
- if (func(node) === false) {
- iteratorState.stop = true;
- return;
- } else {
- // The node is partially selected by the Range, so we can use a new RangeIterator on the portion of
- // the node selected by the Range.
- subRangeIterator = rangeIterator.getSubtreeIterator();
- iterateSubtree(subRangeIterator, func, iteratorState);
- subRangeIterator.detach();
- if (iteratorState.stop) {
- return;
- }
- }
- } else {
- // The whole node is selected, so we can use efficient DOM iteration to iterate over the node and its
- // descendants
- it = dom.createIterator(node);
- while ( (n = it.next()) ) {
- if (func(n) === false) {
- iteratorState.stop = true;
- return;
- }
- }
- }
- }
- }
-
- function deleteSubtree(iterator) {
- var subIterator;
- while (iterator.next()) {
- if (iterator.isPartiallySelectedSubtree()) {
- subIterator = iterator.getSubtreeIterator();
- deleteSubtree(subIterator);
- subIterator.detach();
- } else {
- iterator.remove();
- }
- }
- }
-
- function extractSubtree(iterator) {
- for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) {
-
- if (iterator.isPartiallySelectedSubtree()) {
- node = node.cloneNode(false);
- subIterator = iterator.getSubtreeIterator();
- node.appendChild(extractSubtree(subIterator));
- subIterator.detach();
- } else {
- iterator.remove();
- }
- if (node.nodeType == 10) { // DocumentType
- throw new DOMException("HIERARCHY_REQUEST_ERR");
- }
- frag.appendChild(node);
- }
- return frag;
- }
-
- function getNodesInRange(range, nodeTypes, filter) {
- var filterNodeTypes = !!(nodeTypes && nodeTypes.length), regex;
- var filterExists = !!filter;
- if (filterNodeTypes) {
- regex = new RegExp("^(" + nodeTypes.join("|") + ")$");
- }
-
- var nodes = [];
- iterateSubtree(new RangeIterator(range, false), function(node) {
- if (filterNodeTypes && !regex.test(node.nodeType)) {
- return;
- }
- if (filterExists && !filter(node)) {
- return;
- }
- // Don't include a boundary container if it is a character data node and the range does not contain any
- // of its character data. See issue 190.
- var sc = range.startContainer;
- if (node == sc && isCharacterDataNode(sc) && range.startOffset == sc.length) {
- return;
- }
-
- var ec = range.endContainer;
- if (node == ec && isCharacterDataNode(ec) && range.endOffset == 0) {
- return;
- }
-
- nodes.push(node);
- });
- return nodes;
- }
-
- function inspect(range) {
- var name = (typeof range.getName == "undefined") ? "Range" : range.getName();
- return "[" + name + "(" + dom.inspectNode(range.startContainer) + ":" + range.startOffset + ", " +
- dom.inspectNode(range.endContainer) + ":" + range.endOffset + ")]";
- }
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- // RangeIterator code partially borrows from IERange by Tim Ryan (http://github.com/timcameronryan/IERange)
-
- function RangeIterator(range, clonePartiallySelectedTextNodes) {
- this.range = range;
- this.clonePartiallySelectedTextNodes = clonePartiallySelectedTextNodes;
-
-
- if (!range.collapsed) {
- this.sc = range.startContainer;
- this.so = range.startOffset;
- this.ec = range.endContainer;
- this.eo = range.endOffset;
- var root = range.commonAncestorContainer;
-
- if (this.sc === this.ec && isCharacterDataNode(this.sc)) {
- this.isSingleCharacterDataNode = true;
- this._first = this._last = this._next = this.sc;
- } else {
- this._first = this._next = (this.sc === root && !isCharacterDataNode(this.sc)) ?
- this.sc.childNodes[this.so] : getClosestAncestorIn(this.sc, root, true);
- this._last = (this.ec === root && !isCharacterDataNode(this.ec)) ?
- this.ec.childNodes[this.eo - 1] : getClosestAncestorIn(this.ec, root, true);
- }
- }
- }
-
- RangeIterator.prototype = {
- _current: null,
- _next: null,
- _first: null,
- _last: null,
- isSingleCharacterDataNode: false,
-
- reset: function() {
- this._current = null;
- this._next = this._first;
- },
-
- hasNext: function() {
- return !!this._next;
- },
-
- next: function() {
- // Move to next node
- var current = this._current = this._next;
- if (current) {
- this._next = (current !== this._last) ? current.nextSibling : null;
-
- // Check for partially selected text nodes
- if (isCharacterDataNode(current) && this.clonePartiallySelectedTextNodes) {
- if (current === this.ec) {
- (current = current.cloneNode(true)).deleteData(this.eo, current.length - this.eo);
- }
- if (this._current === this.sc) {
- (current = current.cloneNode(true)).deleteData(0, this.so);
- }
- }
- }
-
- return current;
- },
-
- remove: function() {
- var current = this._current, start, end;
-
- if (isCharacterDataNode(current) && (current === this.sc || current === this.ec)) {
- start = (current === this.sc) ? this.so : 0;
- end = (current === this.ec) ? this.eo : current.length;
- if (start != end) {
- current.deleteData(start, end - start);
- }
- } else {
- if (current.parentNode) {
- current.parentNode.removeChild(current);
- } else {
- }
- }
- },
-
- // Checks if the current node is partially selected
- isPartiallySelectedSubtree: function() {
- var current = this._current;
- return isNonTextPartiallySelected(current, this.range);
- },
-
- getSubtreeIterator: function() {
- var subRange;
- if (this.isSingleCharacterDataNode) {
- subRange = this.range.cloneRange();
- subRange.collapse(false);
- } else {
- subRange = new Range(getRangeDocument(this.range));
- var current = this._current;
- var startContainer = current, startOffset = 0, endContainer = current, endOffset = getNodeLength(current);
-
- if (isOrIsAncestorOf(current, this.sc)) {
- startContainer = this.sc;
- startOffset = this.so;
- }
- if (isOrIsAncestorOf(current, this.ec)) {
- endContainer = this.ec;
- endOffset = this.eo;
- }
-
- updateBoundaries(subRange, startContainer, startOffset, endContainer, endOffset);
- }
- return new RangeIterator(subRange, this.clonePartiallySelectedTextNodes);
- },
-
- detach: function() {
- this.range = this._current = this._next = this._first = this._last = this.sc = this.so = this.ec = this.eo = null;
- }
- };
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- var beforeAfterNodeTypes = [1, 3, 4, 5, 7, 8, 10];
- var rootContainerNodeTypes = [2, 9, 11];
- var readonlyNodeTypes = [5, 6, 10, 12];
- var insertableNodeTypes = [1, 3, 4, 5, 7, 8, 10, 11];
- var surroundNodeTypes = [1, 3, 4, 5, 7, 8];
-
- function createAncestorFinder(nodeTypes) {
- return function(node, selfIsAncestor) {
- var t, n = selfIsAncestor ? node : node.parentNode;
- while (n) {
- t = n.nodeType;
- if (arrayContains(nodeTypes, t)) {
- return n;
- }
- n = n.parentNode;
- }
- return null;
- };
- }
-
- var getDocumentOrFragmentContainer = createAncestorFinder( [9, 11] );
- var getReadonlyAncestor = createAncestorFinder(readonlyNodeTypes);
- var getDocTypeNotationEntityAncestor = createAncestorFinder( [6, 10, 12] );
-
- function assertNoDocTypeNotationEntityAncestor(node, allowSelf) {
- if (getDocTypeNotationEntityAncestor(node, allowSelf)) {
- throw new DOMException("INVALID_NODE_TYPE_ERR");
- }
- }
-
- function assertValidNodeType(node, invalidTypes) {
- if (!arrayContains(invalidTypes, node.nodeType)) {
- throw new DOMException("INVALID_NODE_TYPE_ERR");
- }
- }
-
- function assertValidOffset(node, offset) {
- if (offset < 0 || offset > (isCharacterDataNode(node) ? node.length : node.childNodes.length)) {
- throw new DOMException("INDEX_SIZE_ERR");
- }
- }
-
- function assertSameDocumentOrFragment(node1, node2) {
- if (getDocumentOrFragmentContainer(node1, true) !== getDocumentOrFragmentContainer(node2, true)) {
- throw new DOMException("WRONG_DOCUMENT_ERR");
- }
- }
-
- function assertNodeNotReadOnly(node) {
- if (getReadonlyAncestor(node, true)) {
- throw new DOMException("NO_MODIFICATION_ALLOWED_ERR");
- }
- }
-
- function assertNode(node, codeName) {
- if (!node) {
- throw new DOMException(codeName);
- }
- }
-
- function isOrphan(node) {
- return (crashyTextNodes && dom.isBrokenNode(node)) ||
- !arrayContains(rootContainerNodeTypes, node.nodeType) && !getDocumentOrFragmentContainer(node, true);
- }
-
- function isValidOffset(node, offset) {
- return offset <= (isCharacterDataNode(node) ? node.length : node.childNodes.length);
- }
-
- function isRangeValid(range) {
- return (!!range.startContainer && !!range.endContainer &&
- !isOrphan(range.startContainer) &&
- !isOrphan(range.endContainer) &&
- isValidOffset(range.startContainer, range.startOffset) &&
- isValidOffset(range.endContainer, range.endOffset));
- }
-
- function assertRangeValid(range) {
- if (!isRangeValid(range)) {
- throw new Error("Range error: Range is no longer valid after DOM mutation (" + range.inspect() + ")");
- }
- }
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- // Test the browser's innerHTML support to decide how to implement createContextualFragment
- var styleEl = document.createElement("style");
- var htmlParsingConforms = false;
- try {
- styleEl.innerHTML = "x";
- htmlParsingConforms = (styleEl.firstChild.nodeType == 3); // Opera incorrectly creates an element node
- } catch (e) {
- // IE 6 and 7 throw
- }
-
- api.features.htmlParsingConforms = htmlParsingConforms;
-
- var createContextualFragment = htmlParsingConforms ?
-
- // Implementation as per HTML parsing spec, trusting in the browser's implementation of innerHTML. See
- // discussion and base code for this implementation at issue 67.
- // Spec: http://html5.org/specs/dom-parsing.html#extensions-to-the-range-interface
- // Thanks to Aleks Williams.
- function(fragmentStr) {
- // "Let node the context object's start's node."
- var node = this.startContainer;
- var doc = getDocument(node);
-
- // "If the context object's start's node is null, raise an INVALID_STATE_ERR
- // exception and abort these steps."
- if (!node) {
- throw new DOMException("INVALID_STATE_ERR");
- }
-
- // "Let element be as follows, depending on node's interface:"
- // Document, Document Fragment: null
- var el = null;
-
- // "Element: node"
- if (node.nodeType == 1) {
- el = node;
-
- // "Text, Comment: node's parentElement"
- } else if (isCharacterDataNode(node)) {
- el = dom.parentElement(node);
- }
-
- // "If either element is null or element's ownerDocument is an HTML document
- // and element's local name is "html" and element's namespace is the HTML
- // namespace"
- if (el === null || (
- el.nodeName == "HTML" &&
- dom.isHtmlNamespace(getDocument(el).documentElement) &&
- dom.isHtmlNamespace(el)
- )) {
-
- // "let element be a new Element with "body" as its local name and the HTML
- // namespace as its namespace.""
- el = doc.createElement("body");
- } else {
- el = el.cloneNode(false);
- }
-
- // "If the node's document is an HTML document: Invoke the HTML fragment parsing algorithm."
- // "If the node's document is an XML document: Invoke the XML fragment parsing algorithm."
- // "In either case, the algorithm must be invoked with fragment as the input
- // and element as the context element."
- el.innerHTML = fragmentStr;
-
- // "If this raises an exception, then abort these steps. Otherwise, let new
- // children be the nodes returned."
-
- // "Let fragment be a new DocumentFragment."
- // "Append all new children to fragment."
- // "Return fragment."
- return dom.fragmentFromNodeChildren(el);
- } :
-
- // In this case, innerHTML cannot be trusted, so fall back to a simpler, non-conformant implementation that
- // previous versions of Rangy used (with the exception of using a body element rather than a div)
- function(fragmentStr) {
- var doc = getRangeDocument(this);
- var el = doc.createElement("body");
- el.innerHTML = fragmentStr;
-
- return dom.fragmentFromNodeChildren(el);
- };
-
- function splitRangeBoundaries(range, positionsToPreserve) {
- assertRangeValid(range);
-
- var sc = range.startContainer, so = range.startOffset, ec = range.endContainer, eo = range.endOffset;
- var startEndSame = (sc === ec);
-
- if (isCharacterDataNode(ec) && eo > 0 && eo < ec.length) {
- splitDataNode(ec, eo, positionsToPreserve);
- }
-
- if (isCharacterDataNode(sc) && so > 0 && so < sc.length) {
- sc = splitDataNode(sc, so, positionsToPreserve);
- if (startEndSame) {
- eo -= so;
- ec = sc;
- } else if (ec == sc.parentNode && eo >= getNodeIndex(sc)) {
- eo++;
- }
- so = 0;
- }
- range.setStartAndEnd(sc, so, ec, eo);
- }
-
- function rangeToHtml(range) {
- assertRangeValid(range);
- var container = range.commonAncestorContainer.parentNode.cloneNode(false);
- container.appendChild( range.cloneContents() );
- return container.innerHTML;
- }
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- var rangeProperties = ["startContainer", "startOffset", "endContainer", "endOffset", "collapsed",
- "commonAncestorContainer"];
-
- var s2s = 0, s2e = 1, e2e = 2, e2s = 3;
- var n_b = 0, n_a = 1, n_b_a = 2, n_i = 3;
-
- util.extend(api.rangePrototype, {
- compareBoundaryPoints: function(how, range) {
- assertRangeValid(this);
- assertSameDocumentOrFragment(this.startContainer, range.startContainer);
-
- var nodeA, offsetA, nodeB, offsetB;
- var prefixA = (how == e2s || how == s2s) ? "start" : "end";
- var prefixB = (how == s2e || how == s2s) ? "start" : "end";
- nodeA = this[prefixA + "Container"];
- offsetA = this[prefixA + "Offset"];
- nodeB = range[prefixB + "Container"];
- offsetB = range[prefixB + "Offset"];
- return comparePoints(nodeA, offsetA, nodeB, offsetB);
- },
-
- insertNode: function(node) {
- assertRangeValid(this);
- assertValidNodeType(node, insertableNodeTypes);
- assertNodeNotReadOnly(this.startContainer);
-
- if (isOrIsAncestorOf(node, this.startContainer)) {
- throw new DOMException("HIERARCHY_REQUEST_ERR");
- }
-
- // No check for whether the container of the start of the Range is of a type that does not allow
- // children of the type of node: the browser's DOM implementation should do this for us when we attempt
- // to add the node
-
- var firstNodeInserted = insertNodeAtPosition(node, this.startContainer, this.startOffset);
- this.setStartBefore(firstNodeInserted);
- },
-
- cloneContents: function() {
- assertRangeValid(this);
-
- var clone, frag;
- if (this.collapsed) {
- return getRangeDocument(this).createDocumentFragment();
- } else {
- if (this.startContainer === this.endContainer && isCharacterDataNode(this.startContainer)) {
- clone = this.startContainer.cloneNode(true);
- clone.data = clone.data.slice(this.startOffset, this.endOffset);
- frag = getRangeDocument(this).createDocumentFragment();
- frag.appendChild(clone);
- return frag;
- } else {
- var iterator = new RangeIterator(this, true);
- clone = cloneSubtree(iterator);
- iterator.detach();
- }
- return clone;
- }
- },
-
- canSurroundContents: function() {
- assertRangeValid(this);
- assertNodeNotReadOnly(this.startContainer);
- assertNodeNotReadOnly(this.endContainer);
-
- // Check if the contents can be surrounded. Specifically, this means whether the range partially selects
- // no non-text nodes.
- var iterator = new RangeIterator(this, true);
- var boundariesInvalid = (iterator._first && (isNonTextPartiallySelected(iterator._first, this)) ||
- (iterator._last && isNonTextPartiallySelected(iterator._last, this)));
- iterator.detach();
- return !boundariesInvalid;
- },
-
- surroundContents: function(node) {
- assertValidNodeType(node, surroundNodeTypes);
-
- if (!this.canSurroundContents()) {
- throw new DOMException("INVALID_STATE_ERR");
- }
-
- // Extract the contents
- var content = this.extractContents();
-
- // Clear the children of the node
- if (node.hasChildNodes()) {
- while (node.lastChild) {
- node.removeChild(node.lastChild);
- }
- }
-
- // Insert the new node and add the extracted contents
- insertNodeAtPosition(node, this.startContainer, this.startOffset);
- node.appendChild(content);
-
- this.selectNode(node);
- },
-
- cloneRange: function() {
- assertRangeValid(this);
- var range = new Range(getRangeDocument(this));
- var i = rangeProperties.length, prop;
- while (i--) {
- prop = rangeProperties[i];
- range[prop] = this[prop];
- }
- return range;
- },
-
- toString: function() {
- assertRangeValid(this);
- var sc = this.startContainer;
- if (sc === this.endContainer && isCharacterDataNode(sc)) {
- return (sc.nodeType == 3 || sc.nodeType == 4) ? sc.data.slice(this.startOffset, this.endOffset) : "";
- } else {
- var textParts = [], iterator = new RangeIterator(this, true);
- iterateSubtree(iterator, function(node) {
- // Accept only text or CDATA nodes, not comments
- if (node.nodeType == 3 || node.nodeType == 4) {
- textParts.push(node.data);
- }
- });
- iterator.detach();
- return textParts.join("");
- }
- },
-
- // The methods below are all non-standard. The following batch were introduced by Mozilla but have since
- // been removed from Mozilla.
-
- compareNode: function(node) {
- assertRangeValid(this);
-
- var parent = node.parentNode;
- var nodeIndex = getNodeIndex(node);
-
- if (!parent) {
- throw new DOMException("NOT_FOUND_ERR");
- }
-
- var startComparison = this.comparePoint(parent, nodeIndex),
- endComparison = this.comparePoint(parent, nodeIndex + 1);
-
- if (startComparison < 0) { // Node starts before
- return (endComparison > 0) ? n_b_a : n_b;
- } else {
- return (endComparison > 0) ? n_a : n_i;
- }
- },
-
- comparePoint: function(node, offset) {
- assertRangeValid(this);
- assertNode(node, "HIERARCHY_REQUEST_ERR");
- assertSameDocumentOrFragment(node, this.startContainer);
-
- if (comparePoints(node, offset, this.startContainer, this.startOffset) < 0) {
- return -1;
- } else if (comparePoints(node, offset, this.endContainer, this.endOffset) > 0) {
- return 1;
- }
- return 0;
- },
-
- createContextualFragment: createContextualFragment,
-
- toHtml: function() {
- return rangeToHtml(this);
- },
-
- // touchingIsIntersecting determines whether this method considers a node that borders a range intersects
- // with it (as in WebKit) or not (as in Gecko pre-1.9, and the default)
- intersectsNode: function(node, touchingIsIntersecting) {
- assertRangeValid(this);
- assertNode(node, "NOT_FOUND_ERR");
- if (getDocument(node) !== getRangeDocument(this)) {
- return false;
- }
-
- var parent = node.parentNode, offset = getNodeIndex(node);
- assertNode(parent, "NOT_FOUND_ERR");
-
- var startComparison = comparePoints(parent, offset, this.endContainer, this.endOffset),
- endComparison = comparePoints(parent, offset + 1, this.startContainer, this.startOffset);
-
- return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0;
- },
-
- isPointInRange: function(node, offset) {
- assertRangeValid(this);
- assertNode(node, "HIERARCHY_REQUEST_ERR");
- assertSameDocumentOrFragment(node, this.startContainer);
-
- return (comparePoints(node, offset, this.startContainer, this.startOffset) >= 0) &&
- (comparePoints(node, offset, this.endContainer, this.endOffset) <= 0);
- },
-
- // The methods below are non-standard and invented by me.
-
- // Sharing a boundary start-to-end or end-to-start does not count as intersection.
- intersectsRange: function(range) {
- return rangesIntersect(this, range, false);
- },
-
- // Sharing a boundary start-to-end or end-to-start does count as intersection.
- intersectsOrTouchesRange: function(range) {
- return rangesIntersect(this, range, true);
- },
-
- intersection: function(range) {
- if (this.intersectsRange(range)) {
- var startComparison = comparePoints(this.startContainer, this.startOffset, range.startContainer, range.startOffset),
- endComparison = comparePoints(this.endContainer, this.endOffset, range.endContainer, range.endOffset);
-
- var intersectionRange = this.cloneRange();
- if (startComparison == -1) {
- intersectionRange.setStart(range.startContainer, range.startOffset);
- }
- if (endComparison == 1) {
- intersectionRange.setEnd(range.endContainer, range.endOffset);
- }
- return intersectionRange;
- }
- return null;
- },
-
- union: function(range) {
- if (this.intersectsOrTouchesRange(range)) {
- var unionRange = this.cloneRange();
- if (comparePoints(range.startContainer, range.startOffset, this.startContainer, this.startOffset) == -1) {
- unionRange.setStart(range.startContainer, range.startOffset);
- }
- if (comparePoints(range.endContainer, range.endOffset, this.endContainer, this.endOffset) == 1) {
- unionRange.setEnd(range.endContainer, range.endOffset);
- }
- return unionRange;
- } else {
- throw new DOMException("Ranges do not intersect");
- }
- },
-
- containsNode: function(node, allowPartial) {
- if (allowPartial) {
- return this.intersectsNode(node, false);
- } else {
- return this.compareNode(node) == n_i;
- }
- },
-
- containsNodeContents: function(node) {
- return this.comparePoint(node, 0) >= 0 && this.comparePoint(node, getNodeLength(node)) <= 0;
- },
-
- containsRange: function(range) {
- var intersection = this.intersection(range);
- return intersection !== null && range.equals(intersection);
- },
-
- containsNodeText: function(node) {
- var nodeRange = this.cloneRange();
- nodeRange.selectNode(node);
- var textNodes = nodeRange.getNodes([3]);
- if (textNodes.length > 0) {
- nodeRange.setStart(textNodes[0], 0);
- var lastTextNode = textNodes.pop();
- nodeRange.setEnd(lastTextNode, lastTextNode.length);
- return this.containsRange(nodeRange);
- } else {
- return this.containsNodeContents(node);
- }
- },
-
- getNodes: function(nodeTypes, filter) {
- assertRangeValid(this);
- return getNodesInRange(this, nodeTypes, filter);
- },
-
- getDocument: function() {
- return getRangeDocument(this);
- },
-
- collapseBefore: function(node) {
- this.setEndBefore(node);
- this.collapse(false);
- },
-
- collapseAfter: function(node) {
- this.setStartAfter(node);
- this.collapse(true);
- },
-
- getBookmark: function(containerNode) {
- var doc = getRangeDocument(this);
- var preSelectionRange = api.createRange(doc);
- containerNode = containerNode || dom.getBody(doc);
- preSelectionRange.selectNodeContents(containerNode);
- var range = this.intersection(preSelectionRange);
- var start = 0, end = 0;
- if (range) {
- preSelectionRange.setEnd(range.startContainer, range.startOffset);
- start = preSelectionRange.toString().length;
- end = start + range.toString().length;
- }
-
- return {
- start: start,
- end: end,
- containerNode: containerNode
- };
- },
-
- moveToBookmark: function(bookmark) {
- var containerNode = bookmark.containerNode;
- var charIndex = 0;
- this.setStart(containerNode, 0);
- this.collapse(true);
- var nodeStack = [containerNode], node, foundStart = false, stop = false;
- var nextCharIndex, i, childNodes;
-
- while (!stop && (node = nodeStack.pop())) {
- if (node.nodeType == 3) {
- nextCharIndex = charIndex + node.length;
- if (!foundStart && bookmark.start >= charIndex && bookmark.start <= nextCharIndex) {
- this.setStart(node, bookmark.start - charIndex);
- foundStart = true;
- }
- if (foundStart && bookmark.end >= charIndex && bookmark.end <= nextCharIndex) {
- this.setEnd(node, bookmark.end - charIndex);
- stop = true;
- }
- charIndex = nextCharIndex;
- } else {
- childNodes = node.childNodes;
- i = childNodes.length;
- while (i--) {
- nodeStack.push(childNodes[i]);
- }
- }
- }
- },
-
- getName: function() {
- return "DomRange";
- },
-
- equals: function(range) {
- return Range.rangesEqual(this, range);
- },
-
- isValid: function() {
- return isRangeValid(this);
- },
-
- inspect: function() {
- return inspect(this);
- },
-
- detach: function() {
- // In DOM4, detach() is now a no-op.
- }
- });
-
- function copyComparisonConstantsToObject(obj) {
- obj.START_TO_START = s2s;
- obj.START_TO_END = s2e;
- obj.END_TO_END = e2e;
- obj.END_TO_START = e2s;
-
- obj.NODE_BEFORE = n_b;
- obj.NODE_AFTER = n_a;
- obj.NODE_BEFORE_AND_AFTER = n_b_a;
- obj.NODE_INSIDE = n_i;
- }
-
- function copyComparisonConstants(constructor) {
- copyComparisonConstantsToObject(constructor);
- copyComparisonConstantsToObject(constructor.prototype);
- }
-
- function createRangeContentRemover(remover, boundaryUpdater) {
- return function() {
- assertRangeValid(this);
-
- var sc = this.startContainer, so = this.startOffset, root = this.commonAncestorContainer;
-
- var iterator = new RangeIterator(this, true);
-
- // Work out where to position the range after content removal
- var node, boundary;
- if (sc !== root) {
- node = getClosestAncestorIn(sc, root, true);
- boundary = getBoundaryAfterNode(node);
- sc = boundary.node;
- so = boundary.offset;
- }
-
- // Check none of the range is read-only
- iterateSubtree(iterator, assertNodeNotReadOnly);
-
- iterator.reset();
-
- // Remove the content
- var returnValue = remover(iterator);
- iterator.detach();
-
- // Move to the new position
- boundaryUpdater(this, sc, so, sc, so);
-
- return returnValue;
- };
- }
-
- function createPrototypeRange(constructor, boundaryUpdater) {
- function createBeforeAfterNodeSetter(isBefore, isStart) {
- return function(node) {
- assertValidNodeType(node, beforeAfterNodeTypes);
- assertValidNodeType(getRootContainer(node), rootContainerNodeTypes);
-
- var boundary = (isBefore ? getBoundaryBeforeNode : getBoundaryAfterNode)(node);
- (isStart ? setRangeStart : setRangeEnd)(this, boundary.node, boundary.offset);
- };
- }
-
- function setRangeStart(range, node, offset) {
- var ec = range.endContainer, eo = range.endOffset;
- if (node !== range.startContainer || offset !== range.startOffset) {
- // Check the root containers of the range and the new boundary, and also check whether the new boundary
- // is after the current end. In either case, collapse the range to the new position
- if (getRootContainer(node) != getRootContainer(ec) || comparePoints(node, offset, ec, eo) == 1) {
- ec = node;
- eo = offset;
- }
- boundaryUpdater(range, node, offset, ec, eo);
- }
- }
-
- function setRangeEnd(range, node, offset) {
- var sc = range.startContainer, so = range.startOffset;
- if (node !== range.endContainer || offset !== range.endOffset) {
- // Check the root containers of the range and the new boundary, and also check whether the new boundary
- // is after the current end. In either case, collapse the range to the new position
- if (getRootContainer(node) != getRootContainer(sc) || comparePoints(node, offset, sc, so) == -1) {
- sc = node;
- so = offset;
- }
- boundaryUpdater(range, sc, so, node, offset);
- }
- }
-
- // Set up inheritance
- var F = function() {};
- F.prototype = api.rangePrototype;
- constructor.prototype = new F();
-
- util.extend(constructor.prototype, {
- setStart: function(node, offset) {
- assertNoDocTypeNotationEntityAncestor(node, true);
- assertValidOffset(node, offset);
-
- setRangeStart(this, node, offset);
- },
-
- setEnd: function(node, offset) {
- assertNoDocTypeNotationEntityAncestor(node, true);
- assertValidOffset(node, offset);
-
- setRangeEnd(this, node, offset);
- },
-
- /**
- * Convenience method to set a range's start and end boundaries. Overloaded as follows:
- * - Two parameters (node, offset) creates a collapsed range at that position
- * - Three parameters (node, startOffset, endOffset) creates a range contained with node starting at
- * startOffset and ending at endOffset
- * - Four parameters (startNode, startOffset, endNode, endOffset) creates a range starting at startOffset in
- * startNode and ending at endOffset in endNode
- */
- setStartAndEnd: function() {
- var args = arguments;
- var sc = args[0], so = args[1], ec = sc, eo = so;
-
- switch (args.length) {
- case 3:
- eo = args[2];
- break;
- case 4:
- ec = args[2];
- eo = args[3];
- break;
- }
-
- boundaryUpdater(this, sc, so, ec, eo);
- },
-
- setBoundary: function(node, offset, isStart) {
- this["set" + (isStart ? "Start" : "End")](node, offset);
- },
-
- setStartBefore: createBeforeAfterNodeSetter(true, true),
- setStartAfter: createBeforeAfterNodeSetter(false, true),
- setEndBefore: createBeforeAfterNodeSetter(true, false),
- setEndAfter: createBeforeAfterNodeSetter(false, false),
-
- collapse: function(isStart) {
- assertRangeValid(this);
- if (isStart) {
- boundaryUpdater(this, this.startContainer, this.startOffset, this.startContainer, this.startOffset);
- } else {
- boundaryUpdater(this, this.endContainer, this.endOffset, this.endContainer, this.endOffset);
- }
- },
-
- selectNodeContents: function(node) {
- assertNoDocTypeNotationEntityAncestor(node, true);
-
- boundaryUpdater(this, node, 0, node, getNodeLength(node));
- },
-
- selectNode: function(node) {
- assertNoDocTypeNotationEntityAncestor(node, false);
- assertValidNodeType(node, beforeAfterNodeTypes);
-
- var start = getBoundaryBeforeNode(node), end = getBoundaryAfterNode(node);
- boundaryUpdater(this, start.node, start.offset, end.node, end.offset);
- },
-
- extractContents: createRangeContentRemover(extractSubtree, boundaryUpdater),
-
- deleteContents: createRangeContentRemover(deleteSubtree, boundaryUpdater),
-
- canSurroundContents: function() {
- assertRangeValid(this);
- assertNodeNotReadOnly(this.startContainer);
- assertNodeNotReadOnly(this.endContainer);
-
- // Check if the contents can be surrounded. Specifically, this means whether the range partially selects
- // no non-text nodes.
- var iterator = new RangeIterator(this, true);
- var boundariesInvalid = (iterator._first && isNonTextPartiallySelected(iterator._first, this) ||
- (iterator._last && isNonTextPartiallySelected(iterator._last, this)));
- iterator.detach();
- return !boundariesInvalid;
- },
-
- splitBoundaries: function() {
- splitRangeBoundaries(this);
- },
-
- splitBoundariesPreservingPositions: function(positionsToPreserve) {
- splitRangeBoundaries(this, positionsToPreserve);
- },
-
- normalizeBoundaries: function() {
- assertRangeValid(this);
-
- var sc = this.startContainer, so = this.startOffset, ec = this.endContainer, eo = this.endOffset;
-
- var mergeForward = function(node) {
- var sibling = node.nextSibling;
- if (sibling && sibling.nodeType == node.nodeType) {
- ec = node;
- eo = node.length;
- node.appendData(sibling.data);
- sibling.parentNode.removeChild(sibling);
- }
- };
-
- var mergeBackward = function(node) {
- var sibling = node.previousSibling;
- if (sibling && sibling.nodeType == node.nodeType) {
- sc = node;
- var nodeLength = node.length;
- so = sibling.length;
- node.insertData(0, sibling.data);
- sibling.parentNode.removeChild(sibling);
- if (sc == ec) {
- eo += so;
- ec = sc;
- } else if (ec == node.parentNode) {
- var nodeIndex = getNodeIndex(node);
- if (eo == nodeIndex) {
- ec = node;
- eo = nodeLength;
- } else if (eo > nodeIndex) {
- eo--;
- }
- }
- }
- };
-
- var normalizeStart = true;
-
- if (isCharacterDataNode(ec)) {
- if (ec.length == eo) {
- mergeForward(ec);
- }
- } else {
- if (eo > 0) {
- var endNode = ec.childNodes[eo - 1];
- if (endNode && isCharacterDataNode(endNode)) {
- mergeForward(endNode);
- }
- }
- normalizeStart = !this.collapsed;
- }
-
- if (normalizeStart) {
- if (isCharacterDataNode(sc)) {
- if (so == 0) {
- mergeBackward(sc);
- }
- } else {
- if (so < sc.childNodes.length) {
- var startNode = sc.childNodes[so];
- if (startNode && isCharacterDataNode(startNode)) {
- mergeBackward(startNode);
- }
- }
- }
- } else {
- sc = ec;
- so = eo;
- }
-
- boundaryUpdater(this, sc, so, ec, eo);
- },
-
- collapseToPoint: function(node, offset) {
- assertNoDocTypeNotationEntityAncestor(node, true);
- assertValidOffset(node, offset);
- this.setStartAndEnd(node, offset);
- }
- });
-
- copyComparisonConstants(constructor);
- }
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- // Updates commonAncestorContainer and collapsed after boundary change
- function updateCollapsedAndCommonAncestor(range) {
- range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset);
- range.commonAncestorContainer = range.collapsed ?
- range.startContainer : dom.getCommonAncestor(range.startContainer, range.endContainer);
- }
-
- function updateBoundaries(range, startContainer, startOffset, endContainer, endOffset) {
- range.startContainer = startContainer;
- range.startOffset = startOffset;
- range.endContainer = endContainer;
- range.endOffset = endOffset;
- range.document = dom.getDocument(startContainer);
-
- updateCollapsedAndCommonAncestor(range);
- }
-
- function Range(doc) {
- this.startContainer = doc;
- this.startOffset = 0;
- this.endContainer = doc;
- this.endOffset = 0;
- this.document = doc;
- updateCollapsedAndCommonAncestor(this);
- }
-
- createPrototypeRange(Range, updateBoundaries);
-
- util.extend(Range, {
- rangeProperties: rangeProperties,
- RangeIterator: RangeIterator,
- copyComparisonConstants: copyComparisonConstants,
- createPrototypeRange: createPrototypeRange,
- inspect: inspect,
- toHtml: rangeToHtml,
- getRangeDocument: getRangeDocument,
- rangesEqual: function(r1, r2) {
- return r1.startContainer === r2.startContainer &&
- r1.startOffset === r2.startOffset &&
- r1.endContainer === r2.endContainer &&
- r1.endOffset === r2.endOffset;
- }
- });
-
- api.DomRange = Range;
- });
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- // Wrappers for the browser's native DOM Range and/or TextRange implementation
- api.createCoreModule("WrappedRange", ["DomRange"], function(api, module) {
- var WrappedRange, WrappedTextRange;
- var dom = api.dom;
- var util = api.util;
- var DomPosition = dom.DomPosition;
- var DomRange = api.DomRange;
- var getBody = dom.getBody;
- var getContentDocument = dom.getContentDocument;
- var isCharacterDataNode = dom.isCharacterDataNode;
-
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- if (api.features.implementsDomRange) {
- // This is a wrapper around the browser's native DOM Range. It has two aims:
- // - Provide workarounds for specific browser bugs
- // - provide convenient extensions, which are inherited from Rangy's DomRange
-
- (function() {
- var rangeProto;
- var rangeProperties = DomRange.rangeProperties;
-
- function updateRangeProperties(range) {
- var i = rangeProperties.length, prop;
- while (i--) {
- prop = rangeProperties[i];
- range[prop] = range.nativeRange[prop];
- }
- // Fix for broken collapsed property in IE 9.
- range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset);
- }
-
- function updateNativeRange(range, startContainer, startOffset, endContainer, endOffset) {
- var startMoved = (range.startContainer !== startContainer || range.startOffset != startOffset);
- var endMoved = (range.endContainer !== endContainer || range.endOffset != endOffset);
- var nativeRangeDifferent = !range.equals(range.nativeRange);
-
- // Always set both boundaries for the benefit of IE9 (see issue 35)
- if (startMoved || endMoved || nativeRangeDifferent) {
- range.setEnd(endContainer, endOffset);
- range.setStart(startContainer, startOffset);
- }
- }
-
- var createBeforeAfterNodeSetter;
-
- WrappedRange = function(range) {
- if (!range) {
- throw module.createError("WrappedRange: Range must be specified");
- }
- this.nativeRange = range;
- updateRangeProperties(this);
- };
-
- DomRange.createPrototypeRange(WrappedRange, updateNativeRange);
-
- rangeProto = WrappedRange.prototype;
-
- rangeProto.selectNode = function(node) {
- this.nativeRange.selectNode(node);
- updateRangeProperties(this);
- };
-
- rangeProto.cloneContents = function() {
- return this.nativeRange.cloneContents();
- };
-
- // Due to a long-standing Firefox bug that I have not been able to find a reliable way to detect,
- // insertNode() is never delegated to the native range.
-
- rangeProto.surroundContents = function(node) {
- this.nativeRange.surroundContents(node);
- updateRangeProperties(this);
- };
-
- rangeProto.collapse = function(isStart) {
- this.nativeRange.collapse(isStart);
- updateRangeProperties(this);
- };
-
- rangeProto.cloneRange = function() {
- return new WrappedRange(this.nativeRange.cloneRange());
- };
-
- rangeProto.refresh = function() {
- updateRangeProperties(this);
- };
-
- rangeProto.toString = function() {
- return this.nativeRange.toString();
- };
-
- // Create test range and node for feature detection
-
- var testTextNode = document.createTextNode("test");
- getBody(document).appendChild(testTextNode);
- var range = document.createRange();
-
- /*--------------------------------------------------------------------------------------------------------*/
-
- // Test for Firefox 2 bug that prevents moving the start of a Range to a point after its current end and
- // correct for it
-
- range.setStart(testTextNode, 0);
- range.setEnd(testTextNode, 0);
-
- try {
- range.setStart(testTextNode, 1);
-
- rangeProto.setStart = function(node, offset) {
- this.nativeRange.setStart(node, offset);
- updateRangeProperties(this);
- };
-
- rangeProto.setEnd = function(node, offset) {
- this.nativeRange.setEnd(node, offset);
- updateRangeProperties(this);
- };
-
- createBeforeAfterNodeSetter = function(name) {
- return function(node) {
- this.nativeRange[name](node);
- updateRangeProperties(this);
- };
- };
-
- } catch(ex) {
-
- rangeProto.setStart = function(node, offset) {
- try {
- this.nativeRange.setStart(node, offset);
- } catch (ex) {
- this.nativeRange.setEnd(node, offset);
- this.nativeRange.setStart(node, offset);
- }
- updateRangeProperties(this);
- };
-
- rangeProto.setEnd = function(node, offset) {
- try {
- this.nativeRange.setEnd(node, offset);
- } catch (ex) {
- this.nativeRange.setStart(node, offset);
- this.nativeRange.setEnd(node, offset);
- }
- updateRangeProperties(this);
- };
-
- createBeforeAfterNodeSetter = function(name, oppositeName) {
- return function(node) {
- try {
- this.nativeRange[name](node);
- } catch (ex) {
- this.nativeRange[oppositeName](node);
- this.nativeRange[name](node);
- }
- updateRangeProperties(this);
- };
- };
- }
-
- rangeProto.setStartBefore = createBeforeAfterNodeSetter("setStartBefore", "setEndBefore");
- rangeProto.setStartAfter = createBeforeAfterNodeSetter("setStartAfter", "setEndAfter");
- rangeProto.setEndBefore = createBeforeAfterNodeSetter("setEndBefore", "setStartBefore");
- rangeProto.setEndAfter = createBeforeAfterNodeSetter("setEndAfter", "setStartAfter");
-
- /*--------------------------------------------------------------------------------------------------------*/
-
- // Always use DOM4-compliant selectNodeContents implementation: it's simpler and less code than testing
- // whether the native implementation can be trusted
- rangeProto.selectNodeContents = function(node) {
- this.setStartAndEnd(node, 0, dom.getNodeLength(node));
- };
-
- /*--------------------------------------------------------------------------------------------------------*/
-
- // Test for and correct WebKit bug that has the behaviour of compareBoundaryPoints round the wrong way for
- // constants START_TO_END and END_TO_START: https://bugs.webkit.org/show_bug.cgi?id=20738
-
- range.selectNodeContents(testTextNode);
- range.setEnd(testTextNode, 3);
-
- var range2 = document.createRange();
- range2.selectNodeContents(testTextNode);
- range2.setEnd(testTextNode, 4);
- range2.setStart(testTextNode, 2);
-
- if (range.compareBoundaryPoints(range.START_TO_END, range2) == -1 &&
- range.compareBoundaryPoints(range.END_TO_START, range2) == 1) {
- // This is the wrong way round, so correct for it
-
- rangeProto.compareBoundaryPoints = function(type, range) {
- range = range.nativeRange || range;
- if (type == range.START_TO_END) {
- type = range.END_TO_START;
- } else if (type == range.END_TO_START) {
- type = range.START_TO_END;
- }
- return this.nativeRange.compareBoundaryPoints(type, range);
- };
- } else {
- rangeProto.compareBoundaryPoints = function(type, range) {
- return this.nativeRange.compareBoundaryPoints(type, range.nativeRange || range);
- };
- }
-
- /*--------------------------------------------------------------------------------------------------------*/
-
- // Test for IE 9 deleteContents() and extractContents() bug and correct it. See issue 107.
-
- var el = document.createElement("div");
- el.innerHTML = "123";
- var textNode = el.firstChild;
- var body = getBody(document);
- body.appendChild(el);
-
- range.setStart(textNode, 1);
- range.setEnd(textNode, 2);
- range.deleteContents();
-
- if (textNode.data == "13") {
- // Behaviour is correct per DOM4 Range so wrap the browser's implementation of deleteContents() and
- // extractContents()
- rangeProto.deleteContents = function() {
- this.nativeRange.deleteContents();
- updateRangeProperties(this);
- };
-
- rangeProto.extractContents = function() {
- var frag = this.nativeRange.extractContents();
- updateRangeProperties(this);
- return frag;
- };
- } else {
- }
-
- body.removeChild(el);
- body = null;
-
- /*--------------------------------------------------------------------------------------------------------*/
-
- // Test for existence of createContextualFragment and delegate to it if it exists
- if (util.isHostMethod(range, "createContextualFragment")) {
- rangeProto.createContextualFragment = function(fragmentStr) {
- return this.nativeRange.createContextualFragment(fragmentStr);
- };
- }
-
- /*--------------------------------------------------------------------------------------------------------*/
-
- // Clean up
- getBody(document).removeChild(testTextNode);
-
- rangeProto.getName = function() {
- return "WrappedRange";
- };
-
- api.WrappedRange = WrappedRange;
-
- api.createNativeRange = function(doc) {
- doc = getContentDocument(doc, module, "createNativeRange");
- return doc.createRange();
- };
- })();
- }
-
- if (api.features.implementsTextRange) {
- /*
- This is a workaround for a bug where IE returns the wrong container element from the TextRange's parentElement()
- method. For example, in the following (where pipes denote the selection boundaries):
-
-
-
- var range = document.selection.createRange();
- alert(range.parentElement().id); // Should alert "ul" but alerts "b"
-
- This method returns the common ancestor node of the following:
- - the parentElement() of the textRange
- - the parentElement() of the textRange after calling collapse(true)
- - the parentElement() of the textRange after calling collapse(false)
- */
- var getTextRangeContainerElement = function(textRange) {
- var parentEl = textRange.parentElement();
- var range = textRange.duplicate();
- range.collapse(true);
- var startEl = range.parentElement();
- range = textRange.duplicate();
- range.collapse(false);
- var endEl = range.parentElement();
- var startEndContainer = (startEl == endEl) ? startEl : dom.getCommonAncestor(startEl, endEl);
-
- return startEndContainer == parentEl ? startEndContainer : dom.getCommonAncestor(parentEl, startEndContainer);
- };
-
- var textRangeIsCollapsed = function(textRange) {
- return textRange.compareEndPoints("StartToEnd", textRange) == 0;
- };
-
- // Gets the boundary of a TextRange expressed as a node and an offset within that node. This function started
- // out as an improved version of code found in Tim Cameron Ryan's IERange (http://code.google.com/p/ierange/)
- // but has grown, fixing problems with line breaks in preformatted text, adding workaround for IE TextRange
- // bugs, handling for inputs and images, plus optimizations.
- var getTextRangeBoundaryPosition = function(textRange, wholeRangeContainerElement, isStart, isCollapsed, startInfo) {
- var workingRange = textRange.duplicate();
- workingRange.collapse(isStart);
- var containerElement = workingRange.parentElement();
-
- // Sometimes collapsing a TextRange that's at the start of a text node can move it into the previous node, so
- // check for that
- if (!dom.isOrIsAncestorOf(wholeRangeContainerElement, containerElement)) {
- containerElement = wholeRangeContainerElement;
- }
-
-
- // Deal with nodes that cannot "contain rich HTML markup". In practice, this means form inputs, images and
- // similar. See http://msdn.microsoft.com/en-us/library/aa703950%28VS.85%29.aspx
- if (!containerElement.canHaveHTML) {
- var pos = new DomPosition(containerElement.parentNode, dom.getNodeIndex(containerElement));
- return {
- boundaryPosition: pos,
- nodeInfo: {
- nodeIndex: pos.offset,
- containerElement: pos.node
- }
- };
- }
-
- var workingNode = dom.getDocument(containerElement).createElement("span");
-
- // Workaround for HTML5 Shiv's insane violation of document.createElement(). See Rangy issue 104 and HTML5
- // Shiv issue 64: https://github.com/aFarkas/html5shiv/issues/64
- if (workingNode.parentNode) {
- workingNode.parentNode.removeChild(workingNode);
- }
-
- var comparison, workingComparisonType = isStart ? "StartToStart" : "StartToEnd";
- var previousNode, nextNode, boundaryPosition, boundaryNode;
- var start = (startInfo && startInfo.containerElement == containerElement) ? startInfo.nodeIndex : 0;
- var childNodeCount = containerElement.childNodes.length;
- var end = childNodeCount;
-
- // Check end first. Code within the loop assumes that the endth child node of the container is definitely
- // after the range boundary.
- var nodeIndex = end;
-
- while (true) {
- if (nodeIndex == childNodeCount) {
- containerElement.appendChild(workingNode);
- } else {
- containerElement.insertBefore(workingNode, containerElement.childNodes[nodeIndex]);
- }
- workingRange.moveToElementText(workingNode);
- comparison = workingRange.compareEndPoints(workingComparisonType, textRange);
- if (comparison == 0 || start == end) {
- break;
- } else if (comparison == -1) {
- if (end == start + 1) {
- // We know the endth child node is after the range boundary, so we must be done.
- break;
- } else {
- start = nodeIndex;
- }
- } else {
- end = (end == start + 1) ? start : nodeIndex;
- }
- nodeIndex = Math.floor((start + end) / 2);
- containerElement.removeChild(workingNode);
- }
-
-
- // We've now reached or gone past the boundary of the text range we're interested in
- // so have identified the node we want
- boundaryNode = workingNode.nextSibling;
-
- if (comparison == -1 && boundaryNode && isCharacterDataNode(boundaryNode)) {
- // This is a character data node (text, comment, cdata). The working range is collapsed at the start of
- // the node containing the text range's boundary, so we move the end of the working range to the
- // boundary point and measure the length of its text to get the boundary's offset within the node.
- workingRange.setEndPoint(isStart ? "EndToStart" : "EndToEnd", textRange);
-
- var offset;
-
- if (/[\r\n]/.test(boundaryNode.data)) {
- /*
- For the particular case of a boundary within a text node containing rendered line breaks (within a
- element, for example), we need a slightly complicated approach to get the boundary's offset in
- IE. The facts:
-
- - Each line break is represented as \r in the text node's data/nodeValue properties
- - Each line break is represented as \r\n in the TextRange's 'text' property
- - The 'text' property of the TextRange does not contain trailing line breaks
-
- To get round the problem presented by the final fact above, we can use the fact that TextRange's
- moveStart() and moveEnd() methods return the actual number of characters moved, which is not
- necessarily the same as the number of characters it was instructed to move. The simplest approach is
- to use this to store the characters moved when moving both the start and end of the range to the
- start of the document body and subtracting the start offset from the end offset (the
- "move-negative-gazillion" method). However, this is extremely slow when the document is large and
- the range is near the end of it. Clearly doing the mirror image (i.e. moving the range boundaries to
- the end of the document) has the same problem.
-
- Another approach that works is to use moveStart() to move the start boundary of the range up to the
- end boundary one character at a time and incrementing a counter with the value returned by the
- moveStart() call. However, the check for whether the start boundary has reached the end boundary is
- expensive, so this method is slow (although unlike "move-negative-gazillion" is largely unaffected
- by the location of the range within the document).
-
- The approach used below is a hybrid of the two methods above. It uses the fact that a string
- containing the TextRange's 'text' property with each \r\n converted to a single \r character cannot
- be longer than the text of the TextRange, so the start of the range is moved that length initially
- and then a character at a time to make up for any trailing line breaks not contained in the 'text'
- property. This has good performance in most situations compared to the previous two methods.
- */
- var tempRange = workingRange.duplicate();
- var rangeLength = tempRange.text.replace(/\r\n/g, "\r").length;
-
- offset = tempRange.moveStart("character", rangeLength);
- while ( (comparison = tempRange.compareEndPoints("StartToEnd", tempRange)) == -1) {
- offset++;
- tempRange.moveStart("character", 1);
- }
- } else {
- offset = workingRange.text.length;
- }
- boundaryPosition = new DomPosition(boundaryNode, offset);
- } else {
-
- // If the boundary immediately follows a character data node and this is the end boundary, we should favour
- // a position within that, and likewise for a start boundary preceding a character data node
- previousNode = (isCollapsed || !isStart) && workingNode.previousSibling;
- nextNode = (isCollapsed || isStart) && workingNode.nextSibling;
- if (nextNode && isCharacterDataNode(nextNode)) {
- boundaryPosition = new DomPosition(nextNode, 0);
- } else if (previousNode && isCharacterDataNode(previousNode)) {
- boundaryPosition = new DomPosition(previousNode, previousNode.data.length);
- } else {
- boundaryPosition = new DomPosition(containerElement, dom.getNodeIndex(workingNode));
- }
- }
-
- // Clean up
- workingNode.parentNode.removeChild(workingNode);
-
- return {
- boundaryPosition: boundaryPosition,
- nodeInfo: {
- nodeIndex: nodeIndex,
- containerElement: containerElement
- }
- };
- };
-
- // Returns a TextRange representing the boundary of a TextRange expressed as a node and an offset within that
- // node. This function started out as an optimized version of code found in Tim Cameron Ryan's IERange
- // (http://code.google.com/p/ierange/)
- var createBoundaryTextRange = function(boundaryPosition, isStart) {
- var boundaryNode, boundaryParent, boundaryOffset = boundaryPosition.offset;
- var doc = dom.getDocument(boundaryPosition.node);
- var workingNode, childNodes, workingRange = getBody(doc).createTextRange();
- var nodeIsDataNode = isCharacterDataNode(boundaryPosition.node);
-
- if (nodeIsDataNode) {
- boundaryNode = boundaryPosition.node;
- boundaryParent = boundaryNode.parentNode;
- } else {
- childNodes = boundaryPosition.node.childNodes;
- boundaryNode = (boundaryOffset < childNodes.length) ? childNodes[boundaryOffset] : null;
- boundaryParent = boundaryPosition.node;
- }
-
- // Position the range immediately before the node containing the boundary
- workingNode = doc.createElement("span");
-
- // Making the working element non-empty element persuades IE to consider the TextRange boundary to be within
- // the element rather than immediately before or after it
- workingNode.innerHTML = "feff;";
-
- // insertBefore is supposed to work like appendChild if the second parameter is null. However, a bug report
- // for IERange suggests that it can crash the browser: http://code.google.com/p/ierange/issues/detail?id=12
- if (boundaryNode) {
- boundaryParent.insertBefore(workingNode, boundaryNode);
- } else {
- boundaryParent.appendChild(workingNode);
- }
-
- workingRange.moveToElementText(workingNode);
- workingRange.collapse(!isStart);
-
- // Clean up
- boundaryParent.removeChild(workingNode);
-
- // Move the working range to the text offset, if required
- if (nodeIsDataNode) {
- workingRange[isStart ? "moveStart" : "moveEnd"]("character", boundaryOffset);
- }
-
- return workingRange;
- };
-
- /*------------------------------------------------------------------------------------------------------------*/
-
- // This is a wrapper around a TextRange, providing full DOM Range functionality using rangy's DomRange as a
- // prototype
-
- WrappedTextRange = function(textRange) {
- this.textRange = textRange;
- this.refresh();
- };
-
- WrappedTextRange.prototype = new DomRange(document);
-
- WrappedTextRange.prototype.refresh = function() {
- var start, end, startBoundary;
-
- // TextRange's parentElement() method cannot be trusted. getTextRangeContainerElement() works around that.
- var rangeContainerElement = getTextRangeContainerElement(this.textRange);
-
- if (textRangeIsCollapsed(this.textRange)) {
- end = start = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true,
- true).boundaryPosition;
- } else {
- startBoundary = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true, false);
- start = startBoundary.boundaryPosition;
-
- // An optimization used here is that if the start and end boundaries have the same parent element, the
- // search scope for the end boundary can be limited to exclude the portion of the element that precedes
- // the start boundary
- end = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, false, false,
- startBoundary.nodeInfo).boundaryPosition;
- }
-
- this.setStart(start.node, start.offset);
- this.setEnd(end.node, end.offset);
- };
-
- WrappedTextRange.prototype.getName = function() {
- return "WrappedTextRange";
- };
-
- DomRange.copyComparisonConstants(WrappedTextRange);
-
- var rangeToTextRange = function(range) {
- if (range.collapsed) {
- return createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);
- } else {
- var startRange = createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);
- var endRange = createBoundaryTextRange(new DomPosition(range.endContainer, range.endOffset), false);
- var textRange = getBody( DomRange.getRangeDocument(range) ).createTextRange();
- textRange.setEndPoint("StartToStart", startRange);
- textRange.setEndPoint("EndToEnd", endRange);
- return textRange;
- }
- };
-
- WrappedTextRange.rangeToTextRange = rangeToTextRange;
-
- WrappedTextRange.prototype.toTextRange = function() {
- return rangeToTextRange(this);
- };
-
- api.WrappedTextRange = WrappedTextRange;
-
- // IE 9 and above have both implementations and Rangy makes both available. The next few lines sets which
- // implementation to use by default.
- if (!api.features.implementsDomRange || api.config.preferTextRange) {
- // Add WrappedTextRange as the Range property of the global object to allow expression like Range.END_TO_END to work
- var globalObj = (function() { return this; })();
- if (typeof globalObj.Range == "undefined") {
- globalObj.Range = WrappedTextRange;
- }
-
- api.createNativeRange = function(doc) {
- doc = getContentDocument(doc, module, "createNativeRange");
- return getBody(doc).createTextRange();
- };
-
- api.WrappedRange = WrappedTextRange;
- }
- }
-
- api.createRange = function(doc) {
- doc = getContentDocument(doc, module, "createRange");
- return new api.WrappedRange(api.createNativeRange(doc));
- };
-
- api.createRangyRange = function(doc) {
- doc = getContentDocument(doc, module, "createRangyRange");
- return new DomRange(doc);
- };
-
- api.createIframeRange = function(iframeEl) {
- module.deprecationNotice("createIframeRange()", "createRange(iframeEl)");
- return api.createRange(iframeEl);
- };
-
- api.createIframeRangyRange = function(iframeEl) {
- module.deprecationNotice("createIframeRangyRange()", "createRangyRange(iframeEl)");
- return api.createRangyRange(iframeEl);
- };
-
- api.addShimListener(function(win) {
- var doc = win.document;
- if (typeof doc.createRange == "undefined") {
- doc.createRange = function() {
- return api.createRange(doc);
- };
- }
- doc = win = null;
- });
- });
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- // This module creates a selection object wrapper that conforms as closely as possible to the Selection specification
- // in the HTML Editing spec (http://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#selections)
- api.createCoreModule("WrappedSelection", ["DomRange", "WrappedRange"], function(api, module) {
- api.config.checkSelectionRanges = true;
-
- var BOOLEAN = "boolean";
- var NUMBER = "number";
- var dom = api.dom;
- var util = api.util;
- var isHostMethod = util.isHostMethod;
- var DomRange = api.DomRange;
- var WrappedRange = api.WrappedRange;
- var DOMException = api.DOMException;
- var DomPosition = dom.DomPosition;
- var getNativeSelection;
- var selectionIsCollapsed;
- var features = api.features;
- var CONTROL = "Control";
- var getDocument = dom.getDocument;
- var getBody = dom.getBody;
- var rangesEqual = DomRange.rangesEqual;
-
-
- // Utility function to support direction parameters in the API that may be a string ("backward" or "forward") or a
- // Boolean (true for backwards).
- function isDirectionBackward(dir) {
- return (typeof dir == "string") ? /^backward(s)?$/i.test(dir) : !!dir;
- }
-
- function getWindow(win, methodName) {
- if (!win) {
- return window;
- } else if (dom.isWindow(win)) {
- return win;
- } else if (win instanceof WrappedSelection) {
- return win.win;
- } else {
- var doc = dom.getContentDocument(win, module, methodName);
- return dom.getWindow(doc);
- }
- }
-
- function getWinSelection(winParam) {
- return getWindow(winParam, "getWinSelection").getSelection();
- }
-
- function getDocSelection(winParam) {
- return getWindow(winParam, "getDocSelection").document.selection;
- }
-
- function winSelectionIsBackward(sel) {
- var backward = false;
- if (sel.anchorNode) {
- backward = (dom.comparePoints(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset) == 1);
- }
- return backward;
- }
-
- // Test for the Range/TextRange and Selection features required
- // Test for ability to retrieve selection
- var implementsWinGetSelection = isHostMethod(window, "getSelection"),
- implementsDocSelection = util.isHostObject(document, "selection");
-
- features.implementsWinGetSelection = implementsWinGetSelection;
- features.implementsDocSelection = implementsDocSelection;
-
- var useDocumentSelection = implementsDocSelection && (!implementsWinGetSelection || api.config.preferTextRange);
-
- if (useDocumentSelection) {
- getNativeSelection = getDocSelection;
- api.isSelectionValid = function(winParam) {
- var doc = getWindow(winParam, "isSelectionValid").document, nativeSel = doc.selection;
-
- // Check whether the selection TextRange is actually contained within the correct document
- return (nativeSel.type != "None" || getDocument(nativeSel.createRange().parentElement()) == doc);
- };
- } else if (implementsWinGetSelection) {
- getNativeSelection = getWinSelection;
- api.isSelectionValid = function() {
- return true;
- };
- } else {
- module.fail("Neither document.selection or window.getSelection() detected.");
- }
-
- api.getNativeSelection = getNativeSelection;
-
- var testSelection = getNativeSelection();
- var testRange = api.createNativeRange(document);
- var body = getBody(document);
-
- // Obtaining a range from a selection
- var selectionHasAnchorAndFocus = util.areHostProperties(testSelection,
- ["anchorNode", "focusNode", "anchorOffset", "focusOffset"]);
-
- features.selectionHasAnchorAndFocus = selectionHasAnchorAndFocus;
-
- // Test for existence of native selection extend() method
- var selectionHasExtend = isHostMethod(testSelection, "extend");
- features.selectionHasExtend = selectionHasExtend;
-
- // Test if rangeCount exists
- var selectionHasRangeCount = (typeof testSelection.rangeCount == NUMBER);
- features.selectionHasRangeCount = selectionHasRangeCount;
-
- var selectionSupportsMultipleRanges = false;
- var collapsedNonEditableSelectionsSupported = true;
-
- var addRangeBackwardToNative = selectionHasExtend ?
- function(nativeSelection, range) {
- var doc = DomRange.getRangeDocument(range);
- var endRange = api.createRange(doc);
- endRange.collapseToPoint(range.endContainer, range.endOffset);
- nativeSelection.addRange(getNativeRange(endRange));
- nativeSelection.extend(range.startContainer, range.startOffset);
- } : null;
-
- if (util.areHostMethods(testSelection, ["addRange", "getRangeAt", "removeAllRanges"]) &&
- typeof testSelection.rangeCount == NUMBER && features.implementsDomRange) {
-
- (function() {
- // Previously an iframe was used but this caused problems in some circumstances in IE, so tests are
- // performed on the current document's selection. See issue 109.
-
- // Note also that if a selection previously existed, it is wiped by these tests. This should usually be fine
- // because initialization usually happens when the document loads, but could be a problem for a script that
- // loads and initializes Rangy later. If anyone complains, code could be added to save and restore the
- // selection.
- var sel = window.getSelection();
- if (sel) {
- // Store the current selection
- var originalSelectionRangeCount = sel.rangeCount;
- var selectionHasMultipleRanges = (originalSelectionRangeCount > 1);
- var originalSelectionRanges = [];
- var originalSelectionBackward = winSelectionIsBackward(sel);
- for (var i = 0; i < originalSelectionRangeCount; ++i) {
- originalSelectionRanges[i] = sel.getRangeAt(i);
- }
-
- // Create some test elements
- var body = getBody(document);
- var testEl = body.appendChild( document.createElement("div") );
- testEl.contentEditable = "false";
- var textNode = testEl.appendChild( document.createTextNode("\u00a0\u00a0\u00a0") );
-
- // Test whether the native selection will allow a collapsed selection within a non-editable element
- var r1 = document.createRange();
-
- r1.setStart(textNode, 1);
- r1.collapse(true);
- sel.addRange(r1);
- collapsedNonEditableSelectionsSupported = (sel.rangeCount == 1);
- sel.removeAllRanges();
-
- // Test whether the native selection is capable of supporting multiple ranges.
- if (!selectionHasMultipleRanges) {
- // Doing the original feature test here in Chrome 36 (and presumably later versions) prints a
- // console error of "Discontiguous selection is not supported." that cannot be suppressed. There's
- // nothing we can do about this while retaining the feature test so we have to resort to a browser
- // sniff. I'm not happy about it. See
- // https://code.google.com/p/chromium/issues/detail?id=399791
- var chromeMatch = window.navigator.appVersion.match(/Chrome\/(.*?) /);
- if (chromeMatch && parseInt(chromeMatch[1]) >= 36) {
- selectionSupportsMultipleRanges = false;
- } else {
- var r2 = r1.cloneRange();
- r1.setStart(textNode, 0);
- r2.setEnd(textNode, 3);
- r2.setStart(textNode, 2);
- sel.addRange(r1);
- sel.addRange(r2);
- selectionSupportsMultipleRanges = (sel.rangeCount == 2);
- }
- }
-
- // Clean up
- body.removeChild(testEl);
- sel.removeAllRanges();
-
- for (i = 0; i < originalSelectionRangeCount; ++i) {
- if (i == 0 && originalSelectionBackward) {
- if (addRangeBackwardToNative) {
- addRangeBackwardToNative(sel, originalSelectionRanges[i]);
- } else {
- api.warn("Rangy initialization: original selection was backwards but selection has been restored forwards because the browser does not support Selection.extend");
- sel.addRange(originalSelectionRanges[i]);
- }
- } else {
- sel.addRange(originalSelectionRanges[i]);
- }
- }
- }
- })();
- }
-
- features.selectionSupportsMultipleRanges = selectionSupportsMultipleRanges;
- features.collapsedNonEditableSelectionsSupported = collapsedNonEditableSelectionsSupported;
-
- // ControlRanges
- var implementsControlRange = false, testControlRange;
-
- if (body && isHostMethod(body, "createControlRange")) {
- testControlRange = body.createControlRange();
- if (util.areHostProperties(testControlRange, ["item", "add"])) {
- implementsControlRange = true;
- }
- }
- features.implementsControlRange = implementsControlRange;
-
- // Selection collapsedness
- if (selectionHasAnchorAndFocus) {
- selectionIsCollapsed = function(sel) {
- return sel.anchorNode === sel.focusNode && sel.anchorOffset === sel.focusOffset;
- };
- } else {
- selectionIsCollapsed = function(sel) {
- return sel.rangeCount ? sel.getRangeAt(sel.rangeCount - 1).collapsed : false;
- };
- }
-
- function updateAnchorAndFocusFromRange(sel, range, backward) {
- var anchorPrefix = backward ? "end" : "start", focusPrefix = backward ? "start" : "end";
- sel.anchorNode = range[anchorPrefix + "Container"];
- sel.anchorOffset = range[anchorPrefix + "Offset"];
- sel.focusNode = range[focusPrefix + "Container"];
- sel.focusOffset = range[focusPrefix + "Offset"];
- }
-
- function updateAnchorAndFocusFromNativeSelection(sel) {
- var nativeSel = sel.nativeSelection;
- sel.anchorNode = nativeSel.anchorNode;
- sel.anchorOffset = nativeSel.anchorOffset;
- sel.focusNode = nativeSel.focusNode;
- sel.focusOffset = nativeSel.focusOffset;
- }
-
- function updateEmptySelection(sel) {
- sel.anchorNode = sel.focusNode = null;
- sel.anchorOffset = sel.focusOffset = 0;
- sel.rangeCount = 0;
- sel.isCollapsed = true;
- sel._ranges.length = 0;
- }
-
- function getNativeRange(range) {
- var nativeRange;
- if (range instanceof DomRange) {
- nativeRange = api.createNativeRange(range.getDocument());
- nativeRange.setEnd(range.endContainer, range.endOffset);
- nativeRange.setStart(range.startContainer, range.startOffset);
- } else if (range instanceof WrappedRange) {
- nativeRange = range.nativeRange;
- } else if (features.implementsDomRange && (range instanceof dom.getWindow(range.startContainer).Range)) {
- nativeRange = range;
- }
- return nativeRange;
- }
-
- function rangeContainsSingleElement(rangeNodes) {
- if (!rangeNodes.length || rangeNodes[0].nodeType != 1) {
- return false;
- }
- for (var i = 1, len = rangeNodes.length; i < len; ++i) {
- if (!dom.isAncestorOf(rangeNodes[0], rangeNodes[i])) {
- return false;
- }
- }
- return true;
- }
-
- function getSingleElementFromRange(range) {
- var nodes = range.getNodes();
- if (!rangeContainsSingleElement(nodes)) {
- throw module.createError("getSingleElementFromRange: range " + range.inspect() + " did not consist of a single element");
- }
- return nodes[0];
- }
-
- // Simple, quick test which only needs to distinguish between a TextRange and a ControlRange
- function isTextRange(range) {
- return !!range && typeof range.text != "undefined";
- }
-
- function updateFromTextRange(sel, range) {
- // Create a Range from the selected TextRange
- var wrappedRange = new WrappedRange(range);
- sel._ranges = [wrappedRange];
-
- updateAnchorAndFocusFromRange(sel, wrappedRange, false);
- sel.rangeCount = 1;
- sel.isCollapsed = wrappedRange.collapsed;
- }
-
- function updateControlSelection(sel) {
- // Update the wrapped selection based on what's now in the native selection
- sel._ranges.length = 0;
- if (sel.docSelection.type == "None") {
- updateEmptySelection(sel);
- } else {
- var controlRange = sel.docSelection.createRange();
- if (isTextRange(controlRange)) {
- // This case (where the selection type is "Control" and calling createRange() on the selection returns
- // a TextRange) can happen in IE 9. It happens, for example, when all elements in the selected
- // ControlRange have been removed from the ControlRange and removed from the document.
- updateFromTextRange(sel, controlRange);
- } else {
- sel.rangeCount = controlRange.length;
- var range, doc = getDocument(controlRange.item(0));
- for (var i = 0; i < sel.rangeCount; ++i) {
- range = api.createRange(doc);
- range.selectNode(controlRange.item(i));
- sel._ranges.push(range);
- }
- sel.isCollapsed = sel.rangeCount == 1 && sel._ranges[0].collapsed;
- updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], false);
- }
- }
- }
-
- function addRangeToControlSelection(sel, range) {
- var controlRange = sel.docSelection.createRange();
- var rangeElement = getSingleElementFromRange(range);
-
- // Create a new ControlRange containing all the elements in the selected ControlRange plus the element
- // contained by the supplied range
- var doc = getDocument(controlRange.item(0));
- var newControlRange = getBody(doc).createControlRange();
- for (var i = 0, len = controlRange.length; i < len; ++i) {
- newControlRange.add(controlRange.item(i));
- }
- try {
- newControlRange.add(rangeElement);
- } catch (ex) {
- throw module.createError("addRange(): Element within the specified Range could not be added to control selection (does it have layout?)");
- }
- newControlRange.select();
-
- // Update the wrapped selection based on what's now in the native selection
- updateControlSelection(sel);
- }
-
- var getSelectionRangeAt;
-
- if (isHostMethod(testSelection, "getRangeAt")) {
- // try/catch is present because getRangeAt() must have thrown an error in some browser and some situation.
- // Unfortunately, I didn't write a comment about the specifics and am now scared to take it out. Let that be a
- // lesson to us all, especially me.
- getSelectionRangeAt = function(sel, index) {
- try {
- return sel.getRangeAt(index);
- } catch (ex) {
- return null;
- }
- };
- } else if (selectionHasAnchorAndFocus) {
- getSelectionRangeAt = function(sel) {
- var doc = getDocument(sel.anchorNode);
- var range = api.createRange(doc);
- range.setStartAndEnd(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset);
-
- // Handle the case when the selection was selected backwards (from the end to the start in the
- // document)
- if (range.collapsed !== this.isCollapsed) {
- range.setStartAndEnd(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset);
- }
-
- return range;
- };
- }
-
- function WrappedSelection(selection, docSelection, win) {
- this.nativeSelection = selection;
- this.docSelection = docSelection;
- this._ranges = [];
- this.win = win;
- this.refresh();
- }
-
- WrappedSelection.prototype = api.selectionPrototype;
-
- function deleteProperties(sel) {
- sel.win = sel.anchorNode = sel.focusNode = sel._ranges = null;
- sel.rangeCount = sel.anchorOffset = sel.focusOffset = 0;
- sel.detached = true;
- }
-
- var cachedRangySelections = [];
-
- function actOnCachedSelection(win, action) {
- var i = cachedRangySelections.length, cached, sel;
- while (i--) {
- cached = cachedRangySelections[i];
- sel = cached.selection;
- if (action == "deleteAll") {
- deleteProperties(sel);
- } else if (cached.win == win) {
- if (action == "delete") {
- cachedRangySelections.splice(i, 1);
- return true;
- } else {
- return sel;
- }
- }
- }
- if (action == "deleteAll") {
- cachedRangySelections.length = 0;
- }
- return null;
- }
-
- var getSelection = function(win) {
- // Check if the parameter is a Rangy Selection object
- if (win && win instanceof WrappedSelection) {
- win.refresh();
- return win;
- }
-
- win = getWindow(win, "getNativeSelection");
-
- var sel = actOnCachedSelection(win);
- var nativeSel = getNativeSelection(win), docSel = implementsDocSelection ? getDocSelection(win) : null;
- if (sel) {
- sel.nativeSelection = nativeSel;
- sel.docSelection = docSel;
- sel.refresh();
- } else {
- sel = new WrappedSelection(nativeSel, docSel, win);
- cachedRangySelections.push( { win: win, selection: sel } );
- }
- return sel;
- };
-
- api.getSelection = getSelection;
-
- api.getIframeSelection = function(iframeEl) {
- module.deprecationNotice("getIframeSelection()", "getSelection(iframeEl)");
- return api.getSelection(dom.getIframeWindow(iframeEl));
- };
-
- var selProto = WrappedSelection.prototype;
-
- function createControlSelection(sel, ranges) {
- // Ensure that the selection becomes of type "Control"
- var doc = getDocument(ranges[0].startContainer);
- var controlRange = getBody(doc).createControlRange();
- for (var i = 0, el, len = ranges.length; i < len; ++i) {
- el = getSingleElementFromRange(ranges[i]);
- try {
- controlRange.add(el);
- } catch (ex) {
- throw module.createError("setRanges(): Element within one of the specified Ranges could not be added to control selection (does it have layout?)");
- }
- }
- controlRange.select();
-
- // Update the wrapped selection based on what's now in the native selection
- updateControlSelection(sel);
- }
-
- // Selecting a range
- if (!useDocumentSelection && selectionHasAnchorAndFocus && util.areHostMethods(testSelection, ["removeAllRanges", "addRange"])) {
- selProto.removeAllRanges = function() {
- this.nativeSelection.removeAllRanges();
- updateEmptySelection(this);
- };
-
- var addRangeBackward = function(sel, range) {
- addRangeBackwardToNative(sel.nativeSelection, range);
- sel.refresh();
- };
-
- if (selectionHasRangeCount) {
- selProto.addRange = function(range, direction) {
- if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {
- addRangeToControlSelection(this, range);
- } else {
- if (isDirectionBackward(direction) && selectionHasExtend) {
- addRangeBackward(this, range);
- } else {
- var previousRangeCount;
- if (selectionSupportsMultipleRanges) {
- previousRangeCount = this.rangeCount;
- } else {
- this.removeAllRanges();
- previousRangeCount = 0;
- }
- // Clone the native range so that changing the selected range does not affect the selection.
- // This is contrary to the spec but is the only way to achieve consistency between browsers. See
- // issue 80.
- this.nativeSelection.addRange(getNativeRange(range).cloneRange());
-
- // Check whether adding the range was successful
- this.rangeCount = this.nativeSelection.rangeCount;
-
- if (this.rangeCount == previousRangeCount + 1) {
- // The range was added successfully
-
- // Check whether the range that we added to the selection is reflected in the last range extracted from
- // the selection
- if (api.config.checkSelectionRanges) {
- var nativeRange = getSelectionRangeAt(this.nativeSelection, this.rangeCount - 1);
- if (nativeRange && !rangesEqual(nativeRange, range)) {
- // Happens in WebKit with, for example, a selection placed at the start of a text node
- range = new WrappedRange(nativeRange);
- }
- }
- this._ranges[this.rangeCount - 1] = range;
- updateAnchorAndFocusFromRange(this, range, selectionIsBackward(this.nativeSelection));
- this.isCollapsed = selectionIsCollapsed(this);
- } else {
- // The range was not added successfully. The simplest thing is to refresh
- this.refresh();
- }
- }
- }
- };
- } else {
- selProto.addRange = function(range, direction) {
- if (isDirectionBackward(direction) && selectionHasExtend) {
- addRangeBackward(this, range);
- } else {
- this.nativeSelection.addRange(getNativeRange(range));
- this.refresh();
- }
- };
- }
-
- selProto.setRanges = function(ranges) {
- if (implementsControlRange && implementsDocSelection && ranges.length > 1) {
- createControlSelection(this, ranges);
- } else {
- this.removeAllRanges();
- for (var i = 0, len = ranges.length; i < len; ++i) {
- this.addRange(ranges[i]);
- }
- }
- };
- } else if (isHostMethod(testSelection, "empty") && isHostMethod(testRange, "select") &&
- implementsControlRange && useDocumentSelection) {
-
- selProto.removeAllRanges = function() {
- // Added try/catch as fix for issue #21
- try {
- this.docSelection.empty();
-
- // Check for empty() not working (issue #24)
- if (this.docSelection.type != "None") {
- // Work around failure to empty a control selection by instead selecting a TextRange and then
- // calling empty()
- var doc;
- if (this.anchorNode) {
- doc = getDocument(this.anchorNode);
- } else if (this.docSelection.type == CONTROL) {
- var controlRange = this.docSelection.createRange();
- if (controlRange.length) {
- doc = getDocument( controlRange.item(0) );
- }
- }
- if (doc) {
- var textRange = getBody(doc).createTextRange();
- textRange.select();
- this.docSelection.empty();
- }
- }
- } catch(ex) {}
- updateEmptySelection(this);
- };
-
- selProto.addRange = function(range) {
- if (this.docSelection.type == CONTROL) {
- addRangeToControlSelection(this, range);
- } else {
- api.WrappedTextRange.rangeToTextRange(range).select();
- this._ranges[0] = range;
- this.rangeCount = 1;
- this.isCollapsed = this._ranges[0].collapsed;
- updateAnchorAndFocusFromRange(this, range, false);
- }
- };
-
- selProto.setRanges = function(ranges) {
- this.removeAllRanges();
- var rangeCount = ranges.length;
- if (rangeCount > 1) {
- createControlSelection(this, ranges);
- } else if (rangeCount) {
- this.addRange(ranges[0]);
- }
- };
- } else {
- module.fail("No means of selecting a Range or TextRange was found");
- return false;
- }
-
- selProto.getRangeAt = function(index) {
- if (index < 0 || index >= this.rangeCount) {
- throw new DOMException("INDEX_SIZE_ERR");
- } else {
- // Clone the range to preserve selection-range independence. See issue 80.
- return this._ranges[index].cloneRange();
- }
- };
-
- var refreshSelection;
-
- if (useDocumentSelection) {
- refreshSelection = function(sel) {
- var range;
- if (api.isSelectionValid(sel.win)) {
- range = sel.docSelection.createRange();
- } else {
- range = getBody(sel.win.document).createTextRange();
- range.collapse(true);
- }
-
- if (sel.docSelection.type == CONTROL) {
- updateControlSelection(sel);
- } else if (isTextRange(range)) {
- updateFromTextRange(sel, range);
- } else {
- updateEmptySelection(sel);
- }
- };
- } else if (isHostMethod(testSelection, "getRangeAt") && typeof testSelection.rangeCount == NUMBER) {
- refreshSelection = function(sel) {
- if (implementsControlRange && implementsDocSelection && sel.docSelection.type == CONTROL) {
- updateControlSelection(sel);
- } else {
- sel._ranges.length = sel.rangeCount = sel.nativeSelection.rangeCount;
- if (sel.rangeCount) {
- for (var i = 0, len = sel.rangeCount; i < len; ++i) {
- sel._ranges[i] = new api.WrappedRange(sel.nativeSelection.getRangeAt(i));
- }
- updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], selectionIsBackward(sel.nativeSelection));
- sel.isCollapsed = selectionIsCollapsed(sel);
- } else {
- updateEmptySelection(sel);
- }
- }
- };
- } else if (selectionHasAnchorAndFocus && typeof testSelection.isCollapsed == BOOLEAN && typeof testRange.collapsed == BOOLEAN && features.implementsDomRange) {
- refreshSelection = function(sel) {
- var range, nativeSel = sel.nativeSelection;
- if (nativeSel.anchorNode) {
- range = getSelectionRangeAt(nativeSel, 0);
- sel._ranges = [range];
- sel.rangeCount = 1;
- updateAnchorAndFocusFromNativeSelection(sel);
- sel.isCollapsed = selectionIsCollapsed(sel);
- } else {
- updateEmptySelection(sel);
- }
- };
- } else {
- module.fail("No means of obtaining a Range or TextRange from the user's selection was found");
- return false;
- }
-
- selProto.refresh = function(checkForChanges) {
- var oldRanges = checkForChanges ? this._ranges.slice(0) : null;
- var oldAnchorNode = this.anchorNode, oldAnchorOffset = this.anchorOffset;
-
- refreshSelection(this);
- if (checkForChanges) {
- // Check the range count first
- var i = oldRanges.length;
- if (i != this._ranges.length) {
- return true;
- }
-
- // Now check the direction. Checking the anchor position is the same is enough since we're checking all the
- // ranges after this
- if (this.anchorNode != oldAnchorNode || this.anchorOffset != oldAnchorOffset) {
- return true;
- }
-
- // Finally, compare each range in turn
- while (i--) {
- if (!rangesEqual(oldRanges[i], this._ranges[i])) {
- return true;
- }
- }
- return false;
- }
- };
-
- // Removal of a single range
- var removeRangeManually = function(sel, range) {
- var ranges = sel.getAllRanges();
- sel.removeAllRanges();
- for (var i = 0, len = ranges.length; i < len; ++i) {
- if (!rangesEqual(range, ranges[i])) {
- sel.addRange(ranges[i]);
- }
- }
- if (!sel.rangeCount) {
- updateEmptySelection(sel);
- }
- };
-
- if (implementsControlRange && implementsDocSelection) {
- selProto.removeRange = function(range) {
- if (this.docSelection.type == CONTROL) {
- var controlRange = this.docSelection.createRange();
- var rangeElement = getSingleElementFromRange(range);
-
- // Create a new ControlRange containing all the elements in the selected ControlRange minus the
- // element contained by the supplied range
- var doc = getDocument(controlRange.item(0));
- var newControlRange = getBody(doc).createControlRange();
- var el, removed = false;
- for (var i = 0, len = controlRange.length; i < len; ++i) {
- el = controlRange.item(i);
- if (el !== rangeElement || removed) {
- newControlRange.add(controlRange.item(i));
- } else {
- removed = true;
- }
- }
- newControlRange.select();
-
- // Update the wrapped selection based on what's now in the native selection
- updateControlSelection(this);
- } else {
- removeRangeManually(this, range);
- }
- };
- } else {
- selProto.removeRange = function(range) {
- removeRangeManually(this, range);
- };
- }
-
- // Detecting if a selection is backward
- var selectionIsBackward;
- if (!useDocumentSelection && selectionHasAnchorAndFocus && features.implementsDomRange) {
- selectionIsBackward = winSelectionIsBackward;
-
- selProto.isBackward = function() {
- return selectionIsBackward(this);
- };
- } else {
- selectionIsBackward = selProto.isBackward = function() {
- return false;
- };
- }
-
- // Create an alias for backwards compatibility. From 1.3, everything is "backward" rather than "backwards"
- selProto.isBackwards = selProto.isBackward;
-
- // Selection stringifier
- // This is conformant to the old HTML5 selections draft spec but differs from WebKit and Mozilla's implementation.
- // The current spec does not yet define this method.
- selProto.toString = function() {
- var rangeTexts = [];
- for (var i = 0, len = this.rangeCount; i < len; ++i) {
- rangeTexts[i] = "" + this._ranges[i];
- }
- return rangeTexts.join("");
- };
-
- function assertNodeInSameDocument(sel, node) {
- if (sel.win.document != getDocument(node)) {
- throw new DOMException("WRONG_DOCUMENT_ERR");
- }
- }
-
- // No current browser conforms fully to the spec for this method, so Rangy's own method is always used
- selProto.collapse = function(node, offset) {
- assertNodeInSameDocument(this, node);
- var range = api.createRange(node);
- range.collapseToPoint(node, offset);
- this.setSingleRange(range);
- this.isCollapsed = true;
- };
-
- selProto.collapseToStart = function() {
- if (this.rangeCount) {
- var range = this._ranges[0];
- this.collapse(range.startContainer, range.startOffset);
- } else {
- throw new DOMException("INVALID_STATE_ERR");
- }
- };
-
- selProto.collapseToEnd = function() {
- if (this.rangeCount) {
- var range = this._ranges[this.rangeCount - 1];
- this.collapse(range.endContainer, range.endOffset);
- } else {
- throw new DOMException("INVALID_STATE_ERR");
- }
- };
-
- // The spec is very specific on how selectAllChildren should be implemented so the native implementation is
- // never used by Rangy.
- selProto.selectAllChildren = function(node) {
- assertNodeInSameDocument(this, node);
- var range = api.createRange(node);
- range.selectNodeContents(node);
- this.setSingleRange(range);
- };
-
- selProto.deleteFromDocument = function() {
- // Sepcial behaviour required for IE's control selections
- if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {
- var controlRange = this.docSelection.createRange();
- var element;
- while (controlRange.length) {
- element = controlRange.item(0);
- controlRange.remove(element);
- element.parentNode.removeChild(element);
- }
- this.refresh();
- } else if (this.rangeCount) {
- var ranges = this.getAllRanges();
- if (ranges.length) {
- this.removeAllRanges();
- for (var i = 0, len = ranges.length; i < len; ++i) {
- ranges[i].deleteContents();
- }
- // The spec says nothing about what the selection should contain after calling deleteContents on each
- // range. Firefox moves the selection to where the final selected range was, so we emulate that
- this.addRange(ranges[len - 1]);
- }
- }
- };
-
- // The following are non-standard extensions
- selProto.eachRange = function(func, returnValue) {
- for (var i = 0, len = this._ranges.length; i < len; ++i) {
- if ( func( this.getRangeAt(i) ) ) {
- return returnValue;
- }
- }
- };
-
- selProto.getAllRanges = function() {
- var ranges = [];
- this.eachRange(function(range) {
- ranges.push(range);
- });
- return ranges;
- };
-
- selProto.setSingleRange = function(range, direction) {
- this.removeAllRanges();
- this.addRange(range, direction);
- };
-
- selProto.callMethodOnEachRange = function(methodName, params) {
- var results = [];
- this.eachRange( function(range) {
- results.push( range[methodName].apply(range, params) );
- } );
- return results;
- };
-
- function createStartOrEndSetter(isStart) {
- return function(node, offset) {
- var range;
- if (this.rangeCount) {
- range = this.getRangeAt(0);
- range["set" + (isStart ? "Start" : "End")](node, offset);
- } else {
- range = api.createRange(this.win.document);
- range.setStartAndEnd(node, offset);
- }
- this.setSingleRange(range, this.isBackward());
- };
- }
-
- selProto.setStart = createStartOrEndSetter(true);
- selProto.setEnd = createStartOrEndSetter(false);
-
- // Add select() method to Range prototype. Any existing selection will be removed.
- api.rangePrototype.select = function(direction) {
- getSelection( this.getDocument() ).setSingleRange(this, direction);
- };
-
- selProto.changeEachRange = function(func) {
- var ranges = [];
- var backward = this.isBackward();
-
- this.eachRange(function(range) {
- func(range);
- ranges.push(range);
- });
-
- this.removeAllRanges();
- if (backward && ranges.length == 1) {
- this.addRange(ranges[0], "backward");
- } else {
- this.setRanges(ranges);
- }
- };
-
- selProto.containsNode = function(node, allowPartial) {
- return this.eachRange( function(range) {
- return range.containsNode(node, allowPartial);
- }, true ) || false;
- };
-
- selProto.getBookmark = function(containerNode) {
- return {
- backward: this.isBackward(),
- rangeBookmarks: this.callMethodOnEachRange("getBookmark", [containerNode])
- };
- };
-
- selProto.moveToBookmark = function(bookmark) {
- var selRanges = [];
- for (var i = 0, rangeBookmark, range; rangeBookmark = bookmark.rangeBookmarks[i++]; ) {
- range = api.createRange(this.win);
- range.moveToBookmark(rangeBookmark);
- selRanges.push(range);
- }
- if (bookmark.backward) {
- this.setSingleRange(selRanges[0], "backward");
- } else {
- this.setRanges(selRanges);
- }
- };
-
- selProto.toHtml = function() {
- var rangeHtmls = [];
- this.eachRange(function(range) {
- rangeHtmls.push( DomRange.toHtml(range) );
- });
- return rangeHtmls.join("");
- };
-
- if (features.implementsTextRange) {
- selProto.getNativeTextRange = function() {
- var sel, textRange;
- if ( (sel = this.docSelection) ) {
- var range = sel.createRange();
- if (isTextRange(range)) {
- return range;
- } else {
- throw module.createError("getNativeTextRange: selection is a control selection");
- }
- } else if (this.rangeCount > 0) {
- return api.WrappedTextRange.rangeToTextRange( this.getRangeAt(0) );
- } else {
- throw module.createError("getNativeTextRange: selection contains no range");
- }
- };
- }
-
- function inspect(sel) {
- var rangeInspects = [];
- var anchor = new DomPosition(sel.anchorNode, sel.anchorOffset);
- var focus = new DomPosition(sel.focusNode, sel.focusOffset);
- var name = (typeof sel.getName == "function") ? sel.getName() : "Selection";
-
- if (typeof sel.rangeCount != "undefined") {
- for (var i = 0, len = sel.rangeCount; i < len; ++i) {
- rangeInspects[i] = DomRange.inspect(sel.getRangeAt(i));
- }
- }
- return "[" + name + "(Ranges: " + rangeInspects.join(", ") +
- ")(anchor: " + anchor.inspect() + ", focus: " + focus.inspect() + "]";
- }
-
- selProto.getName = function() {
- return "WrappedSelection";
- };
-
- selProto.inspect = function() {
- return inspect(this);
- };
-
- selProto.detach = function() {
- actOnCachedSelection(this.win, "delete");
- deleteProperties(this);
- };
-
- WrappedSelection.detachAll = function() {
- actOnCachedSelection(null, "deleteAll");
- };
-
- WrappedSelection.inspect = inspect;
- WrappedSelection.isDirectionBackward = isDirectionBackward;
-
- api.Selection = WrappedSelection;
-
- api.selectionPrototype = selProto;
-
- api.addShimListener(function(win) {
- if (typeof win.getSelection == "undefined") {
- win.getSelection = function() {
- return getSelection(win);
- };
- }
- win = null;
- });
- });
-
-
- /*----------------------------------------------------------------------------------------------------------------*/
-
- return api;
-}, this);;/**
- * Selection save and restore module for Rangy.
- * Saves and restores user selections using marker invisible elements in the DOM.
- *
- * Part of Rangy, a cross-browser JavaScript range and selection library
- * http://code.google.com/p/rangy/
- *
- * Depends on Rangy core.
- *
- * Copyright 2014, Tim Down
- * Licensed under the MIT license.
- * Version: 1.3alpha.20140804
- * Build date: 4 August 2014
- */
-(function(factory, global) {
- if (typeof define == "function" && define.amd) {
- // AMD. Register as an anonymous module with a dependency on Rangy.
- define(["rangy"], factory);
- /*
- } else if (typeof exports == "object") {
- // Node/CommonJS style for Browserify
- module.exports = factory;
- */
- } else {
- // No AMD or CommonJS support so we use the rangy global variable
- factory(global.rangy);
- }
-})(function(rangy) {
- rangy.createModule("SaveRestore", ["WrappedRange"], function(api, module) {
- var dom = api.dom;
-
- var markerTextChar = "\ufeff";
-
- function gEBI(id, doc) {
- return (doc || document).getElementById(id);
- }
-
- function insertRangeBoundaryMarker(range, atStart) {
- var markerId = "selectionBoundary_" + (+new Date()) + "_" + ("" + Math.random()).slice(2);
- var markerEl;
- var doc = dom.getDocument(range.startContainer);
-
- // Clone the Range and collapse to the appropriate boundary point
- var boundaryRange = range.cloneRange();
- boundaryRange.collapse(atStart);
-
- // Create the marker element containing a single invisible character using DOM methods and insert it
- markerEl = doc.createElement("span");
- markerEl.id = markerId;
- markerEl.style.lineHeight = "0";
- markerEl.style.display = "none";
- markerEl.className = "rangySelectionBoundary";
- markerEl.appendChild(doc.createTextNode(markerTextChar));
-
- boundaryRange.insertNode(markerEl);
- return markerEl;
- }
-
- function setRangeBoundary(doc, range, markerId, atStart) {
- var markerEl = gEBI(markerId, doc);
- if (markerEl) {
- range[atStart ? "setStartBefore" : "setEndBefore"](markerEl);
- markerEl.parentNode.removeChild(markerEl);
- } else {
- module.warn("Marker element has been removed. Cannot restore selection.");
- }
- }
-
- function compareRanges(r1, r2) {
- return r2.compareBoundaryPoints(r1.START_TO_START, r1);
- }
-
- function saveRange(range, backward) {
- var startEl, endEl, doc = api.DomRange.getRangeDocument(range), text = range.toString();
-
- if (range.collapsed) {
- endEl = insertRangeBoundaryMarker(range, false);
- return {
- document: doc,
- markerId: endEl.id,
- collapsed: true
- };
- } else {
- endEl = insertRangeBoundaryMarker(range, false);
- startEl = insertRangeBoundaryMarker(range, true);
-
- return {
- document: doc,
- startMarkerId: startEl.id,
- endMarkerId: endEl.id,
- collapsed: false,
- backward: backward,
- toString: function() {
- return "original text: '" + text + "', new text: '" + range.toString() + "'";
- }
- };
- }
- }
-
- function restoreRange(rangeInfo, normalize) {
- var doc = rangeInfo.document;
- if (typeof normalize == "undefined") {
- normalize = true;
- }
- var range = api.createRange(doc);
- if (rangeInfo.collapsed) {
- var markerEl = gEBI(rangeInfo.markerId, doc);
- if (markerEl) {
- markerEl.style.display = "inline";
- var previousNode = markerEl.previousSibling;
-
- // Workaround for issue 17
- if (previousNode && previousNode.nodeType == 3) {
- markerEl.parentNode.removeChild(markerEl);
- range.collapseToPoint(previousNode, previousNode.length);
- } else {
- range.collapseBefore(markerEl);
- markerEl.parentNode.removeChild(markerEl);
- }
- } else {
- module.warn("Marker element has been removed. Cannot restore selection.");
- }
- } else {
- setRangeBoundary(doc, range, rangeInfo.startMarkerId, true);
- setRangeBoundary(doc, range, rangeInfo.endMarkerId, false);
- }
-
- if (normalize) {
- range.normalizeBoundaries();
- }
-
- return range;
- }
-
- function saveRanges(ranges, backward) {
- var rangeInfos = [], range, doc;
-
- // Order the ranges by position within the DOM, latest first, cloning the array to leave the original untouched
- ranges = ranges.slice(0);
- ranges.sort(compareRanges);
-
- for (var i = 0, len = ranges.length; i < len; ++i) {
- rangeInfos[i] = saveRange(ranges[i], backward);
- }
-
- // Now that all the markers are in place and DOM manipulation over, adjust each range's boundaries to lie
- // between its markers
- for (i = len - 1; i >= 0; --i) {
- range = ranges[i];
- doc = api.DomRange.getRangeDocument(range);
- if (range.collapsed) {
- range.collapseAfter(gEBI(rangeInfos[i].markerId, doc));
- } else {
- range.setEndBefore(gEBI(rangeInfos[i].endMarkerId, doc));
- range.setStartAfter(gEBI(rangeInfos[i].startMarkerId, doc));
- }
- }
-
- return rangeInfos;
- }
-
- function saveSelection(win) {
- if (!api.isSelectionValid(win)) {
- module.warn("Cannot save selection. This usually happens when the selection is collapsed and the selection document has lost focus.");
- return null;
- }
- var sel = api.getSelection(win);
- var ranges = sel.getAllRanges();
- var backward = (ranges.length == 1 && sel.isBackward());
-
- var rangeInfos = saveRanges(ranges, backward);
-
- // Ensure current selection is unaffected
- if (backward) {
- sel.setSingleRange(ranges[0], "backward");
- } else {
- sel.setRanges(ranges);
- }
-
- return {
- win: win,
- rangeInfos: rangeInfos,
- restored: false
- };
- }
-
- function restoreRanges(rangeInfos) {
- var ranges = [];
-
- // Ranges are in reverse order of appearance in the DOM. We want to restore earliest first to avoid
- // normalization affecting previously restored ranges.
- var rangeCount = rangeInfos.length;
-
- for (var i = rangeCount - 1; i >= 0; i--) {
- ranges[i] = restoreRange(rangeInfos[i], true);
- }
-
- return ranges;
- }
-
- function restoreSelection(savedSelection, preserveDirection) {
- if (!savedSelection.restored) {
- var rangeInfos = savedSelection.rangeInfos;
- var sel = api.getSelection(savedSelection.win);
- var ranges = restoreRanges(rangeInfos), rangeCount = rangeInfos.length;
-
- if (rangeCount == 1 && preserveDirection && api.features.selectionHasExtend && rangeInfos[0].backward) {
- sel.removeAllRanges();
- sel.addRange(ranges[0], true);
- } else {
- sel.setRanges(ranges);
- }
-
- savedSelection.restored = true;
- }
- }
-
- function removeMarkerElement(doc, markerId) {
- var markerEl = gEBI(markerId, doc);
- if (markerEl) {
- markerEl.parentNode.removeChild(markerEl);
- }
- }
-
- function removeMarkers(savedSelection) {
- var rangeInfos = savedSelection.rangeInfos;
- for (var i = 0, len = rangeInfos.length, rangeInfo; i < len; ++i) {
- rangeInfo = rangeInfos[i];
- if (rangeInfo.collapsed) {
- removeMarkerElement(savedSelection.doc, rangeInfo.markerId);
- } else {
- removeMarkerElement(savedSelection.doc, rangeInfo.startMarkerId);
- removeMarkerElement(savedSelection.doc, rangeInfo.endMarkerId);
- }
- }
- }
-
- api.util.extend(api, {
- saveRange: saveRange,
- restoreRange: restoreRange,
- saveRanges: saveRanges,
- restoreRanges: restoreRanges,
- saveSelection: saveSelection,
- restoreSelection: restoreSelection,
- removeMarkerElement: removeMarkerElement,
- removeMarkers: removeMarkers
- });
- });
-
-}, this);;/*
- Base.js, version 1.1a
- Copyright 2006-2010, Dean Edwards
- License: http://www.opensource.org/licenses/mit-license.php
-*/
-
-var Base = function() {
- // dummy
-};
-
-Base.extend = function(_instance, _static) { // subclass
- var extend = Base.prototype.extend;
-
- // build the prototype
- Base._prototyping = true;
- var proto = new this;
- extend.call(proto, _instance);
- proto.base = function() {
- // call this method from any other method to invoke that method's ancestor
- };
- delete Base._prototyping;
-
- // create the wrapper for the constructor function
- //var constructor = proto.constructor.valueOf(); //-dean
- var constructor = proto.constructor;
- var klass = proto.constructor = function() {
- if (!Base._prototyping) {
- if (this._constructing || this.constructor == klass) { // instantiation
- this._constructing = true;
- constructor.apply(this, arguments);
- delete this._constructing;
- } else if (arguments[0] != null) { // casting
- return (arguments[0].extend || extend).call(arguments[0], proto);
- }
- }
- };
-
- // build the class interface
- klass.ancestor = this;
- klass.extend = this.extend;
- klass.forEach = this.forEach;
- klass.implement = this.implement;
- klass.prototype = proto;
- klass.toString = this.toString;
- klass.valueOf = function(type) {
- //return (type == "object") ? klass : constructor; //-dean
- return (type == "object") ? klass : constructor.valueOf();
- };
- extend.call(klass, _static);
- // class initialisation
- if (typeof klass.init == "function") klass.init();
- return klass;
-};
-
-Base.prototype = {
- extend: function(source, value) {
- if (arguments.length > 1) { // extending with a name/value pair
- var ancestor = this[source];
- if (ancestor && (typeof value == "function") && // overriding a method?
- // the valueOf() comparison is to avoid circular references
- (!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) &&
- /\bbase\b/.test(value)) {
- // get the underlying method
- var method = value.valueOf();
- // override
- value = function() {
- var previous = this.base || Base.prototype.base;
- this.base = ancestor;
- var returnValue = method.apply(this, arguments);
- this.base = previous;
- return returnValue;
- };
- // point to the underlying method
- value.valueOf = function(type) {
- return (type == "object") ? value : method;
- };
- value.toString = Base.toString;
- }
- this[source] = value;
- } else if (source) { // extending with an object literal
- var extend = Base.prototype.extend;
- // if this object has a customised extend method then use it
- if (!Base._prototyping && typeof this != "function") {
- extend = this.extend || extend;
- }
- var proto = {toSource: null};
- // do the "toString" and other methods manually
- var hidden = ["constructor", "toString", "valueOf"];
- // if we are prototyping then include the constructor
- var i = Base._prototyping ? 0 : 1;
- while (key = hidden[i++]) {
- if (source[key] != proto[key]) {
- extend.call(this, key, source[key]);
-
- }
- }
- // copy each of the source object's properties to this object
- for (var key in source) {
- if (!proto[key]) extend.call(this, key, source[key]);
- }
- }
- return this;
- }
-};
-
-// initialise
-Base = Base.extend({
- constructor: function() {
- this.extend(arguments[0]);
- }
-}, {
- ancestor: Object,
- version: "1.1",
-
- forEach: function(object, block, context) {
- for (var key in object) {
- if (this.prototype[key] === undefined) {
- block.call(context, object[key], key, object);
- }
- }
- },
-
- implement: function() {
- for (var i = 0; i < arguments.length; i++) {
- if (typeof arguments[i] == "function") {
- // if it's a function, call it
- arguments[i](this.prototype);
- } else {
- // add the interface using the extend method
- this.prototype.extend(arguments[i]);
- }
- }
- return this;
- },
-
- toString: function() {
- return String(this.valueOf());
- }
-});;/**
- * Detect browser support for specific features
- */
-wysihtml5.browser = (function() {
- var userAgent = navigator.userAgent,
- testElement = document.createElement("div"),
- // Browser sniffing is unfortunately needed since some behaviors are impossible to feature detect
- isGecko = userAgent.indexOf("Gecko") !== -1 && userAgent.indexOf("KHTML") === -1,
- isWebKit = userAgent.indexOf("AppleWebKit/") !== -1,
- isChrome = userAgent.indexOf("Chrome/") !== -1,
- isOpera = userAgent.indexOf("Opera/") !== -1;
-
- function iosVersion(userAgent) {
- return +((/ipad|iphone|ipod/.test(userAgent) && userAgent.match(/ os (\d+).+? like mac os x/)) || [undefined, 0])[1];
- }
-
- function androidVersion(userAgent) {
- return +(userAgent.match(/android (\d+)/) || [undefined, 0])[1];
- }
-
- function isIE(version, equation) {
- var rv = -1,
- re;
-
- if (navigator.appName == 'Microsoft Internet Explorer') {
- re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
- } else if (navigator.appName == 'Netscape') {
- re = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})");
- }
-
- if (re && re.exec(navigator.userAgent) != null) {
- rv = parseFloat(RegExp.$1);
- }
-
- if (rv === -1) { return false; }
- if (!version) { return true; }
- if (!equation) { return version === rv; }
- if (equation === "<") { return version < rv; }
- if (equation === ">") { return version > rv; }
- if (equation === "<=") { return version <= rv; }
- if (equation === ">=") { return version >= rv; }
- }
-
- return {
- // Static variable needed, publicly accessible, to be able override it in unit tests
- USER_AGENT: userAgent,
-
- /**
- * Exclude browsers that are not capable of displaying and handling
- * contentEditable as desired:
- * - iPhone, iPad (tested iOS 4.2.2) and Android (tested 2.2) refuse to make contentEditables focusable
- * - IE < 8 create invalid markup and crash randomly from time to time
- *
- * @return {Boolean}
- */
- supported: function() {
- var userAgent = this.USER_AGENT.toLowerCase(),
- // Essential for making html elements editable
- hasContentEditableSupport = "contentEditable" in testElement,
- // Following methods are needed in order to interact with the contentEditable area
- hasEditingApiSupport = document.execCommand && document.queryCommandSupported && document.queryCommandState,
- // document selector apis are only supported by IE 8+, Safari 4+, Chrome and Firefox 3.5+
- hasQuerySelectorSupport = document.querySelector && document.querySelectorAll,
- // contentEditable is unusable in mobile browsers (tested iOS 4.2.2, Android 2.2, Opera Mobile, WebOS 3.05)
- isIncompatibleMobileBrowser = (this.isIos() && iosVersion(userAgent) < 5) || (this.isAndroid() && androidVersion(userAgent) < 4) || userAgent.indexOf("opera mobi") !== -1 || userAgent.indexOf("hpwos/") !== -1;
- return hasContentEditableSupport
- && hasEditingApiSupport
- && hasQuerySelectorSupport
- && !isIncompatibleMobileBrowser;
- },
-
- isTouchDevice: function() {
- return this.supportsEvent("touchmove");
- },
-
- isIos: function() {
- return (/ipad|iphone|ipod/i).test(this.USER_AGENT);
- },
-
- isAndroid: function() {
- return this.USER_AGENT.indexOf("Android") !== -1;
- },
-
- /**
- * Whether the browser supports sandboxed iframes
- * Currently only IE 6+ offers such feature