diff --git a/cms/Readme.md b/cms/Readme.md new file mode 100644 index 0000000..e69de29 diff --git a/cms/cms.ecf b/cms/cms.ecf new file mode 100644 index 0000000..6aa2623 --- /dev/null +++ b/cms/cms.ecf @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + /EIFGENs$ + /CVS$ + /.svn$ + + + + diff --git a/cms/src/configuration/cms_configuration.e b/cms/src/configuration/cms_configuration.e new file mode 100644 index 0000000..b6f6b12 --- /dev/null +++ b/cms/src/configuration/cms_configuration.e @@ -0,0 +1,298 @@ +class + CMS_CONFIGURATION + +inherit + ANY + + SHARED_EXECUTION_ENVIRONMENT + export + {NONE} all + end + +create + make + +feature {NONE} -- Initialization + + make (a_layout: CMS_LAYOUT) + -- Initialize `Current'. + local + p: PATH + do + layout := a_layout + create options.make_equal (10) + configuration_location := layout.cms_config_ini_path + import_from_path (layout.cms_config_ini_path) + analyze + end + + analyze + do + get_root_location + get_var_location + get_themes_location + get_files_location + end + +feature -- Access + + + configuration_location: detachable PATH + + option (a_name: READABLE_STRING_GENERAL): detachable ANY + do + Result := options.item (a_name) + end + + options: STRING_TABLE [STRING_32] + +feature -- Conversion + + append_to_string (s: STRING) + local + utf: UTF_CONVERTER + do + s.append ("Options:%N") + across + options as c + loop + s.append (c.key.to_string_8) + s.append_character ('=') + utf.string_32_into_utf_8_string_8 (c.item, s) + s.append_character ('%N') + end + + s.append ("Specific:%N") + s.append ("root_location=" + root_location.utf_8_name + "%N") + s.append ("var_location=" + var_location.utf_8_name + "%N") + s.append ("files_location=" + files_location.utf_8_name + "%N") + s.append ("themes_location=" + themes_location.utf_8_name + "%N") + end + +feature -- Element change + + set_option (a_name: READABLE_STRING_GENERAL; a_value: STRING_32) + do + options.force (a_value, a_name.as_string_8) + end + +feature -- Access + + var_location: PATH + + root_location: PATH + + files_location: PATH + + themes_location: PATH + + theme_name (dft: detachable like theme_name): READABLE_STRING_8 + do + if attached options.item ("theme") as s then + Result := s + elseif dft /= Void then + Result := dft + else + Result := "default" + end + end + + site_id: READABLE_STRING_8 + do + if attached options.item ("site.id") as s then + Result := s + else + Result := "_EWF_CMS_NO_ID_" + end + end + + site_name (dft: like site_name): READABLE_STRING_8 + do + if attached options.item ("site.name") as s then + Result := s + else + Result := dft + end + end + + site_url (dft: like site_url): READABLE_STRING_8 + do + if attached options.item ("site.url") as s then + Result := s + else + Result := dft + end + if Result /= Void then + if Result.is_empty then + -- ok + elseif not Result.ends_with ("/") then + Result := Result + "/" + end + end + end + + site_script_url (dft: like site_script_url): detachable READABLE_STRING_8 + do + if attached options.item ("site.script_url") as s then + Result := s + else + Result := dft + end + if Result /= Void then + if Result.is_empty then + elseif not Result.ends_with ("/") then + Result := Result + "/" + end + end + end + + site_email (dft: like site_email): READABLE_STRING_8 + do + if attached options.item ("site.email") as s then + Result := s + else + Result := dft + end + end + +feature -- Change + + get_var_location + local + utf: UTF_CONVERTER + do + if attached options.item ("var-dir") as s then + create var_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s)) + else + var_location := execution_environment.current_working_path + end + end + + get_root_location + local + utf: UTF_CONVERTER + do + root_location := layout.www_path + end + + get_files_location + local + utf: UTF_CONVERTER + do + if attached options.item ("files-dir") as s then + create files_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s)) + else + create files_location.make_from_string ("files") + end + end + + get_themes_location + local + utf: UTF_CONVERTER + do + if attached options.item ("themes-dir") as s then + create themes_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s)) + else + themes_location := root_location.extended ("themes") + end + end + +feature {NONE} -- Implementation + + import_from_file (fn: READABLE_STRING_GENERAL) + do + import_from_path (create {PATH}.make_from_string (fn)) + end + + import_from_path (a_filename: PATH) + -- Import ini file content + local + f: PLAIN_TEXT_FILE + l,v: STRING_8 + p: INTEGER + do + create f.make_with_path (a_filename) + if f.exists and f.is_readable then + f.open_read + from + f.read_line + until + f.exhausted + loop + l := f.last_string + l.left_adjust + if not l.is_empty then + if l[1] = '#' then + -- commented line + else + p := l.index_of ('=', 1) + if p > 1 then + v := l.substring (p + 1, l.count) + l.keep_head (p - 1) + v.left_adjust + v.right_adjust + l.right_adjust + + if l.is_case_insensitive_equal ("@include") then + import_from_file (resolved_string (v)) + else + set_option (l.as_lower, resolved_string (v)) + end + end + end + end + f.read_line + end + f.close + end + end + +feature {NONE} -- Environment + + resolved_string (s: READABLE_STRING_8): STRING_32 + -- Resolved `s' using `options' or else environment variables. + local + i,n,b,e: INTEGER + k: detachable READABLE_STRING_8 + do + from + i := 1 + n := s.count + create Result.make (s.count) + until + i > n + loop + if i + 1 < n and then s[i] = '$' and then s[i+1] = '{' then + b := i + 2 + e := s.index_of ('}', b) - 1 + if e > 0 then + k := s.substring (b, e) + if attached option (k) as v then + if attached {READABLE_STRING_32} v as s32 then + Result.append (s32) + else + Result.append (v.out) + end + i := e + 1 + elseif attached execution_environment.item (k) as v then + Result.append (v) + i := e + 1 + else + Result.extend (s[i]) + end + else + Result.extend (s[i]) + end + else + Result.extend (s[i]) + end + i := i + 1 + end + end + + +feature -- Implementation + + layout: CMS_LAYOUT + -- Cms layout +end diff --git a/cms/src/configuration/cms_custom_setup.e b/cms/src/configuration/cms_custom_setup.e new file mode 100644 index 0000000..c8640b1 --- /dev/null +++ b/cms/src/configuration/cms_custom_setup.e @@ -0,0 +1,14 @@ +note + description: "Summary description for {CMS_CUSTOM_SETUP}." + date: "$Date$" + revision: "$Revision$" + +class + CMS_CUSTOM_SETUP + +inherit + CMS_DEFAULT_SETUP + +create + make +end diff --git a/cms/src/configuration/cms_default_setup.e b/cms/src/configuration/cms_default_setup.e new file mode 100644 index 0000000..74f0754 --- /dev/null +++ b/cms/src/configuration/cms_default_setup.e @@ -0,0 +1,123 @@ +note + description: "Summary description for {CMS_DEFAULT_SETUP}." + date: "$Date$" + revision: "$Revision$" + +class + CMS_DEFAULT_SETUP + +inherit + CMS_SETUP + + REFACTORING_HELPER +create + make +feature {NONE} -- Initialization + + make (a_layout: CMS_LAYOUT) + do + layout := a_layout + create configuration.make (layout) + + site_id := configuration.site_id + site_url := configuration.site_url ("") + site_name := configuration.site_name ("EWF::CMS") + site_email := configuration.site_email ("webmaster") + site_dir := configuration.root_location + site_var_dir := configuration.var_location + files_location := configuration.files_location + themes_location := configuration.themes_location + theme_name := configuration.theme_name ("default") + + compute_theme_location + compute_theme_resource_location + + initialize + end + + + initialize + do + build_api_service + build_auth_engine + build_mailer + build_modules + end + +feature -- Access + + modules: ARRAYED_LIST [CMS_MODULE] + -- List of possible modules + + is_html: BOOLEAN + -- + do + -- Enable change the mode + Result := (create {CMS_JSON_CONFIGURATION}).is_html_mode(layout.application_config_path) + end + + is_web: BOOLEAN + -- + do + Result := (create {CMS_JSON_CONFIGURATION}).is_web_mode(layout.application_config_path) + + end + +feature {NONE} -- Initialization + + build_modules + -- Core modules. (User, Admin, Node) + -- At the moment only node is supported. + local + m: CMS_MODULE + do + create modules.make (3) + +-- -- Core +-- create {USER_MODULE} m.make +-- m.enable +-- modules.extend (m) + +-- create {ADMIN_MODULE} m.make +-- m.enable +-- modules.extend (m) + + create {NODE_MODULE} m.make (Current) + m.enable + modules.extend (m) + end + + build_api_service + local + dn: PATH + l_database: DATABASE_CONNECTION + do + to_implement ("Refactor database setup") + if attached (create {JSON_CONFIGURATION}).new_database_configuration (layout.application_config_path) as l_database_config then + create {DATABASE_CONNECTION_MYSQL} l_database.login_with_connection_string (l_database_config.connection_string) + create api_service.make (create {CMS_STORAGE_MYSQL}.make (l_database)) + else + create {DATABASE_CONNECTION_NULL} l_database.make_common + create api_service.make (create {CMS_STORAGE_NULL}) + end + end + + build_auth_engine + do + to_implement ("Not implemented authentication") + end + + build_mailer + do + to_implement ("Not implemented mailer") + end + +feature -- Change + + add_module (m: CMS_MODULE) + -- Add a module `m' to the list of modules `modules'. + do + modules.force (m) + end + +end diff --git a/cms/src/configuration/cms_json_configuration.e b/cms/src/configuration/cms_json_configuration.e new file mode 100644 index 0000000..6462a30 --- /dev/null +++ b/cms/src/configuration/cms_json_configuration.e @@ -0,0 +1,47 @@ +note + description: "Summary description for {CMS_JSON_CONFIGURATION}." + date: "$Date$" + revision: "$Revision$" + +class + CMS_JSON_CONFIGURATION + + +inherit + + JSON_CONFIGURATION + +feature -- Access + + is_html_mode (a_path: PATH): BOOLEAN + -- Is the server running on web mode? + local + l_parser: JSON_PARSER + do + if attached json_file_from (a_path) as json_file then + l_parser := new_json_parser (json_file) + if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then + attached {JSON_OBJECT} jv.item ("server") as l_server and then + attached {JSON_STRING} l_server.item ("mode") as l_mode then + Result := l_mode.item.is_case_insensitive_equal_general ("html") + end + end + end + + + + is_web_mode (a_path: PATH): BOOLEAN + -- Is the server running on web mode? + local + l_parser: JSON_PARSER + do + if attached json_file_from (a_path) as json_file then + l_parser := new_json_parser (json_file) + if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then + attached {JSON_OBJECT} jv.item ("server") as l_server and then + attached {JSON_STRING} l_server.item ("mode") as l_mode then + Result := l_mode.item.is_case_insensitive_equal_general ("web") + end + end + end +end diff --git a/cms/src/configuration/cms_layout.e b/cms/src/configuration/cms_layout.e new file mode 100644 index 0000000..b48684e --- /dev/null +++ b/cms/src/configuration/cms_layout.e @@ -0,0 +1,32 @@ +note + description: "Summary description for {CMS_LAYOUT}." + date: "$Date$" + revision: "$Revision$" + +class + CMS_LAYOUT + +inherit + + APPLICATION_LAYOUT + +create + make_default, + make_with_path + + +feature -- Access + + theme_path: PATH + -- Directory for templates (HTML, etc). + once + Result := www_path.extended ("theme") + end + + cms_config_ini_path: PATH + -- Database Configuration file path. + once + Result := config_path.extended ("cms.ini") + end + +end diff --git a/cms/src/configuration/cms_setup.e b/cms/src/configuration/cms_setup.e new file mode 100644 index 0000000..a9f8327 --- /dev/null +++ b/cms/src/configuration/cms_setup.e @@ -0,0 +1,85 @@ +note + description: "Summary description for {CMS_SETUP}." + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_SETUP + +feature -- Access + + configuration: CMS_CONFIGURATION + -- cms configuration. + + layout: CMS_LAYOUT + -- CMS layout. + + api_service: CMS_API_SERVICE + -- cms api service. + + modules: LIST[CMS_MODULE] + -- Possible list of modules. + -- |If we remove Modules from setup. + -- |we can let the CMS_SERVICE define the basic modules. + deferred + end + + is_html: BOOLEAN + -- api with progresive enhacements css and js, server side rendering. + deferred + end + + is_web: BOOLEAN + -- web: Web Site with progresive enhacements css and js and Ajax calls. + deferred + end + +feature -- Access: Site + + site_id: READABLE_STRING_8 + + site_name: READABLE_STRING_32 + + site_email: READABLE_STRING_8 + + site_url: READABLE_STRING_8 + + site_dir: PATH + + site_var_dir: PATH + + files_location: PATH + +feature -- Access:Theme + + themes_location: PATH + + theme_location: PATH + + theme_resource_location: PATH + -- + + theme_information_location: PATH + -- theme informations. + do + Result := theme_location.extended ("theme.info") + end + + theme_name: READABLE_STRING_32 + -- theme name + +feature -- Compute location + + compute_theme_location + do + theme_location := themes_location.extended (theme_name) + end + + compute_theme_resource_location + -- assets (js, css, images, etc) + -- Not used at the moment. + do + theme_resource_location := theme_location + end + +end diff --git a/cms/src/kernel/cms_html_page.e b/cms/src/kernel/cms_html_page.e new file mode 100644 index 0000000..5c6a5c0 --- /dev/null +++ b/cms/src/kernel/cms_html_page.e @@ -0,0 +1,183 @@ +note + description: "Summary description for {CMS_HTML_PAGE}." + date: "$Date$" + revision: "$Revision$" + +class + CMS_HTML_PAGE + +create + make, + make_typed + +feature {NONE} -- Initialization + + make_typed (a_type: like type) + -- Make current page with optional page type `a_type'. + do + make + type := a_type + end + + make + do + create regions.make (5) + language := "en" + status_code := {HTTP_STATUS_CODE}.ok + create header.make + create {ARRAYED_LIST [STRING]} head_lines.make (5) + header.put_content_type_text_html + create variables.make (0) + end + +feature -- Access + + type: detachable READABLE_STRING_8 + -- Optional page type. + -- such as "front", "about", ... that could be customized by themes. + + title: detachable STRING + + language: STRING + + head_lines: LIST [STRING] + + head_lines_to_string: STRING + do + create Result.make_empty + across + head_lines as h + loop + Result.append (h.item) + Result.append_character ('%N') + end + end + + variables: STRING_TABLE [detachable ANY] + +feature -- Status + + status_code: INTEGER + +feature -- Header + + header: HTTP_HEADER + +feature -- Region + + regions: HASH_TABLE [STRING_8, STRING_8] + -- header + -- content + -- footer + -- could have sidebar first, sidebar second, ... + + region (n: STRING_8): STRING_8 + do + if attached regions.item (n) as r then + Result := r + else + Result := "" + debug + Result := "{{" + n + "}}" + end + end + end + + header_region: STRING_8 + do + Result := region ("header") + end + + content_region: STRING_8 + do + Result := region ("content") + end + + footer_region: STRING_8 + do + Result := region ("content") + end + +feature -- Element change + + register_variable (a_value: detachable ANY; k: READABLE_STRING_GENERAL) + do + variables.force (a_value, k) + end + + add_to_region (s: STRING; k: STRING) + local + r: detachable STRING + do + r := regions.item (k) + if r = Void then + create r.make_from_string (s) + set_region (r, k) + else + r.append (s) + end + end + + add_to_header_region (s: STRING) + do + add_to_region (s, "header") + end + + add_to_content_region (s: STRING) + do + add_to_region (s, "content") + end + + add_to_footer_region (s: STRING) + do + add_to_region (s, "footer") + end + + set_region (s: STRING; k: STRING) + do + regions.force (s, k) + end + + set_header_region (s: STRING) + do + set_region (s, "header") + end + + set_content_region (s: STRING) + do + set_region (s, "content") + end + + set_footer_region (s: STRING) + do + set_region (s, "footer") + end + +feature -- Element change + + set_status_code (c: like status_code) + do + status_code := c + end + + set_language (s: like language) + do + language := s + end + + set_title (s: like title) + do + title := s + end + +note + copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/cms/src/modules/cms_module.e b/cms/src/modules/cms_module.e new file mode 100644 index 0000000..4a40053 --- /dev/null +++ b/cms/src/modules/cms_module.e @@ -0,0 +1,48 @@ +note + description: "Summary description for {WSF_CMS_MODULE}." + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_MODULE + +feature -- Access + + is_enabled: BOOLEAN + + name: STRING + + description: STRING + + package: STRING + + version: STRING + +feature -- Router + + router: WSF_ROUTER + -- Router configuration. + deferred + end + +feature -- Settings + + enable + do + is_enabled := True + end + + disable + do + is_enabled := False + end + +feature -- Hooks + + help_text (a_path: STRING): STRING + do + create Result.make_empty + end + + +end diff --git a/cms/src/modules/node/handler/node_content_handler.e b/cms/src/modules/node/handler/node_content_handler.e new file mode 100644 index 0000000..7fe8fc3 --- /dev/null +++ b/cms/src/modules/node/handler/node_content_handler.e @@ -0,0 +1,189 @@ +note + description: "Summary description for {NEW_CONTENT_HANDLER}." + date: "$Date$" + revision: "$Revision$" + +class + NODE_CONTENT_HANDLER + +inherit + + CMS_HANDLER + + WSF_FILTER + + WSF_URI_HANDLER + rename + execute as uri_execute, + new_mapping as new_uri_mapping + end + + WSF_URI_TEMPLATE_HANDLER + rename + execute as uri_template_execute, + new_mapping as new_uri_template_mapping + select + new_uri_template_mapping + end + + WSF_RESOURCE_HANDLER_HELPER + redefine + do_get, + do_post, + do_put + end + + REFACTORING_HELPER + +create + make + +feature -- execute + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + execute_next (req, res) + end + + uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + end + + uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + end + +feature -- HTTP Methods + + do_get (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + local + l_page: CMS_RESPONSE + do + if attached current_user_name (req) then + -- Existing node + if attached {WSF_STRING} req.path_parameter ("id") as l_id then + if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + create {NODE_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_content") + l_page.add_variable (l_node.content, "content") + l_page.add_variable (l_id.value, "id") + l_page.execute + else + do_error (req, res, l_id) + end + else + -- Todo extract method + to_implement ("Check how to implemet API error") +-- create l_page.make (req, "master2/error.tpl") +-- l_page.set_value ("500", "code") +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to (res) + end + else + (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) + end + end + + + do_post (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + local + u_node: CMS_NODE + do + if attached current_user_name (req) then + if attached {WSF_STRING} req.path_parameter ("id") as l_id then + if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + if attached {WSF_STRING} req.form_parameter ("method") as l_method then + if l_method.is_case_insensitive_equal ("PUT") then + do_put (req, res) + else + to_implement ("Check how to implement API error") +-- create l_page.make (req, "master2/error.tpl") +-- l_page.set_value ("500", "code") +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to (res) + end + end + else + do_error (req, res, l_id) + end + else + to_implement ("Check how to implement API error") +-- create l_page.make (req, "master2/error.tpl") +-- l_page.set_value ("500", "code") +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to (res) + end + else + (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) + end + end + + do_put (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + local + u_node: CMS_NODE +-- l_page: ROC_RESPONSE + do + to_implement ("Check if user has permissions") + if attached current_user (req) as l_user then + if attached {WSF_STRING} req.path_parameter ("id") as l_id then + if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + u_node := extract_data_form (req) + u_node.set_id (l_id.integer_value) + api_service.update_node_content (l_user.id, u_node.id, u_node.content) + (create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url ("")) + else + do_error (req, res, l_id) + end + else + to_implement ("Check how to implement API error") +-- create l_page.make (req, "master2/error.tpl") +-- l_page.set_value ("500", "code") +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to (res) + end + else + (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) + end + end +feature -- Error + + do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING) + -- Handling error. + local + do + to_implement ("Check how to implement API error") +-- create l_page.make (req, "master2/error.tpl") +-- if a_id.is_integer then +-- -- resource not found +-- l_page.set_value ("404", "code") +-- else +-- -- bad request +-- l_page.set_value ("400", "code") +-- end +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to(res) + end + + +feature -- {NONE} Form data + + + extract_data_form (req: WSF_REQUEST): CMS_NODE + -- Extract request form data and build a object + -- Node + do + create Result.make ("", "", "") + if attached {WSF_STRING}req.form_parameter ("content") as l_content then + Result.set_content (l_content.value) + end + end + +end diff --git a/cms/src/modules/node/handler/node_handler.e b/cms/src/modules/node/handler/node_handler.e new file mode 100644 index 0000000..1580099 --- /dev/null +++ b/cms/src/modules/node/handler/node_handler.e @@ -0,0 +1,221 @@ +note + description: "Summary description for {NODE_HANDLER}." + date: "$Date$" + revision: "$Revision$" + +class + NODE_HANDLER + +inherit + CMS_HANDLER + + WSF_FILTER + + WSF_URI_HANDLER + rename + execute as uri_execute, + new_mapping as new_uri_mapping + end + + WSF_URI_TEMPLATE_HANDLER + rename + execute as uri_template_execute, + new_mapping as new_uri_template_mapping + select + new_uri_template_mapping + end + + WSF_RESOURCE_HANDLER_HELPER + redefine + do_get, + do_post, + do_put, + do_delete + end + + REFACTORING_HELPER + +create + make + +feature -- execute + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + execute_next (req, res) + end + + uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + end + + uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + end + +feature -- HTTP Methods + + do_get (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + local + l_page: CMS_RESPONSE + do + -- Existing node + if attached {WSF_STRING} req.path_parameter ("id") as l_id then + if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + create {NODE_VIEW_CMS_RESPONSE} l_page.make (req, res, setup,"modules/node") + l_page.add_variable (l_node, "node") + l_page.execute + else + do_error (req, res, l_id) + end + else + -- Factory + new_node (req, res) + end + end + + do_post (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + local + u_node: CMS_NODE + l_page: CMS_RESPONSE + do + to_implement ("Check user permissions!!!") + if attached current_user (req) as l_user then + if attached {WSF_STRING} req.path_parameter ("id") as l_id then + if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + if attached {WSF_STRING} req.form_parameter ("method") as l_method then + if l_method.is_case_insensitive_equal ("DELETE") then + do_delete (req, res) + elseif l_method.is_case_insensitive_equal ("PUT") then + do_put (req, res) + else + to_implement ("Implement specific responses for 500 pages") + create {NODE_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "master2/error") + l_page.add_variable ("500", "code") + l_page.add_variable (req.absolute_script_url (req.path_info), "request") + l_page.execute + end + end + else + do_error (req, res, l_id) + end + else + -- New node + u_node := extract_data_form (req) + u_node.set_author (l_user) + api_service.new_node (u_node) + (create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url ("")) + end + else + (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) + end + end + + do_put (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + local + u_node: CMS_NODE + do + + if attached current_user (req) as l_user then + if attached {WSF_STRING} req.path_parameter ("id") as l_id then + if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + u_node := extract_data_form (req) + u_node.set_id (l_id.integer_value) + api_service.update_node (l_user.id,u_node) + (create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url ("")) + else + do_error (req, res, l_id) + end + else + -- Internal server error + end + else + (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) + end + + end + + do_delete (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + do + if attached current_user_name (req) then + if attached {WSF_STRING} req.path_parameter ("id") as l_id then + if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + api_service.delete_node (l_id.integer_value) + (create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url ("")) + else + do_error (req, res, l_id) + end + else + -- Internal server error + end + else + (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) + end + end + +feature -- Error + + do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING) + -- Handling error. + local + l_page: CMS_RESPONSE + do + to_implement ("Not implemented") +-- create l_page.make (req, "master2/error.tpl") +-- if a_id.is_integer then +-- -- resource not found +-- l_page.set_value ("404", "code") +-- else +-- -- bad request +-- l_page.set_value ("400", "code") +-- end +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to (res) + end + +feature {NONE} -- Node + + new_node (req: WSF_REQUEST; res: WSF_RESPONSE) + local + l_page: CMS_RESPONSE + do + if attached current_user_name (req) then + create {NODE_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node") + l_page.add_variable (setup.is_html, "html") + l_page.add_variable (setup.is_web, "web") + l_page.execute + + else + (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) + end + end + +feature -- {NONE} Form data + + extract_data_form (req: WSF_REQUEST): CMS_NODE + -- Extract request form data and build a object + -- Node + do + create Result.make ("", "", "") + if attached {WSF_STRING} req.form_parameter ("title") as l_title then + Result.set_title (l_title.value) + end + if attached {WSF_STRING} req.form_parameter ("summary") as l_summary then + Result.set_summary (l_summary.value) + end + if attached {WSF_STRING} req.form_parameter ("content") as l_content then + Result.set_content (l_content.value) + end + end + +end diff --git a/cms/src/modules/node/handler/node_summary_handler.e b/cms/src/modules/node/handler/node_summary_handler.e new file mode 100644 index 0000000..9e38e96 --- /dev/null +++ b/cms/src/modules/node/handler/node_summary_handler.e @@ -0,0 +1,189 @@ +note + description: "Summary description for {NODE_SUMMARY_HANDLER}." + date: "$Date$" + revision: "$Revision$" + +class + NODE_SUMMARY_HANDLER + +inherit + CMS_HANDLER + + WSF_FILTER + + WSF_URI_HANDLER + rename + execute as uri_execute, + new_mapping as new_uri_mapping + end + + WSF_URI_TEMPLATE_HANDLER + rename + execute as uri_template_execute, + new_mapping as new_uri_template_mapping + select + new_uri_template_mapping + end + + WSF_RESOURCE_HANDLER_HELPER + redefine + do_get, + do_post, + do_put + end + + REFACTORING_HELPER + +create + make + +feature -- execute + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + execute_next (req, res) + end + + uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + end + + uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + end + +feature -- HTTP Methods + + do_get (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + local + l_page: CMS_RESPONSE + do + if attached current_user_name (req) then + -- Existing node + if attached {WSF_STRING} req.path_parameter ("id") as l_id then + if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + create {NODE_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_summary") + l_page.add_variable (setup.is_html, "html") + l_page.add_variable (setup.is_web, "web") + l_page.add_variable (l_node.summary, "summary") + l_page.add_variable (l_id.value, "id") + l_page.execute + else + do_error (req, res, l_id) + end + else + to_implement ("Check how to implement API error") +-- create l_page.make (req, "master2/error.tpl") +-- l_page.set_value ("500", "code") +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to (res) + end + else + (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) + end + end + + + do_post (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + local + u_node: CMS_NODE + do + if attached current_user_name (req) then + if attached {WSF_STRING} req.path_parameter ("id") as l_id then + if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + if attached {WSF_STRING} req.form_parameter ("method") as l_method then + if l_method.is_case_insensitive_equal ("PUT") then + do_put (req, res) + else + to_implement ("Check how to implement API error") +-- create l_page.make (req, "master2/error.tpl") +-- l_page.set_value ("500", "code") +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to (res) + end + end + else + do_error (req, res, l_id) + end + else + to_implement ("Check how to implement API error") +-- create l_page.make (req, "master2/error.tpl") +-- l_page.set_value ("500", "code") +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to (res) + end + else + (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) + end + end + + do_put (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + local + u_node: CMS_NODE + do + to_implement ("Check if user has permissions!!!") + if attached current_user (req) as l_user then + if attached {WSF_STRING} req.path_parameter ("id") as l_id then + if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + u_node := extract_data_form (req) + u_node.set_id (l_id.integer_value) + api_service.update_node_summary (l_user.id,u_node.id, u_node.summary) + (create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url ("")) + else + do_error (req, res, l_id) + end + else + to_implement ("Check how to implement API error") +-- create l_page.make (req, "master2/error.tpl") +-- l_page.set_value ("500", "code") +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to (res) + end + else + (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) + end + end + +feature -- Error + + do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING) + -- Handling error. + local +-- l_page: ROC_RESPONSE + do +-- create l_page.make (req, "master2/error.tpl") +-- if a_id.is_integer then +-- -- resource not found +-- l_page.set_value ("404", "code") +-- else +-- -- bad request +-- l_page.set_value ("400", "code") +-- end +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to(res) + end + + +feature -- {NONE} Form data + + + extract_data_form (req: WSF_REQUEST): CMS_NODE + -- Extract request form data and build a object + -- Node + do + create Result.make ("", "", "") + if attached {WSF_STRING}req.form_parameter ("summary") as l_summary then + Result.set_summary (l_summary.value) + end + end + +end diff --git a/cms/src/modules/node/handler/node_title_handler.e b/cms/src/modules/node/handler/node_title_handler.e new file mode 100644 index 0000000..7218ddc --- /dev/null +++ b/cms/src/modules/node/handler/node_title_handler.e @@ -0,0 +1,187 @@ +note + description: "Summary description for {NODE_TITLE_HANDLER}." + date: "$Date$" + revision: "$Revision$" + +class + NODE_TITLE_HANDLER + +inherit + CMS_HANDLER + + WSF_FILTER + + WSF_URI_HANDLER + rename + execute as uri_execute, + new_mapping as new_uri_mapping + end + + WSF_URI_TEMPLATE_HANDLER + rename + execute as uri_template_execute, + new_mapping as new_uri_template_mapping + select + new_uri_template_mapping + end + + WSF_RESOURCE_HANDLER_HELPER + redefine + do_get, + do_post, + do_put + end + + REFACTORING_HELPER + +create + make + +feature -- execute + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + execute_next (req, res) + end + + uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + end + + uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + end + +feature -- HTTP Methods + + do_get (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + local + l_page: CMS_RESPONSE + do + if attached current_user_name (req) as l_user then + -- Existing node + if attached {WSF_STRING} req.path_parameter ("id") as l_id then + if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + create {NODE_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_title") + l_page.add_variable (setup.is_html, "html") + l_page.add_variable (setup.is_web, "web") + l_page.add_variable (l_node.title, "title") + l_page.add_variable (l_id.value, "id") + l_page.execute + else + do_error (req, res, l_id) + end + else + to_implement ("Check how to implement API error") +-- create l_page.make (req, "master2/error.tpl") +-- l_page.set_value ("500", "code") +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to (res) + end + else + (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) + end + end + + do_post (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + local + u_node: CMS_NODE + do + if attached current_user_name (req) as l_user then + if attached {WSF_STRING} req.path_parameter ("id") as l_id then + if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + if attached {WSF_STRING} req.form_parameter ("method") as l_method then + if l_method.is_case_insensitive_equal ("PUT") then + do_put (req, res) + else + to_implement ("Check how to implement API error") +-- create l_page.make (req, "master2/error.tpl") +-- l_page.set_value ("500", "code") +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to (res) + end + end + else + do_error (req, res, l_id) + end + else + to_implement ("Check how to implement API error") +-- create l_page.make (req, "master2/error.tpl") +-- l_page.set_value ("500", "code") +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to (res) + end + else + (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) + end + end + + do_put (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + local + u_node: CMS_NODE + do + to_implement ("Check if user has permissions") + if attached current_user (req) as l_user then + if attached {WSF_STRING} req.path_parameter ("id") as l_id then + if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + u_node := extract_data_form (req) + u_node.set_id (l_id.integer_value) + api_service.update_node_title (l_user.id,u_node.id, u_node.title) + (create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url ("")) + else + do_error (req, res, l_id) + end + else + to_implement ("check how to implement API error") +-- create l_page.make (req, "master2/error.tpl") +-- l_page.set_value ("500", "code") +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to (res) + end + else + (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) + end + end + +feature -- Error + + do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING) + -- Handling error. + local + do + to_implement ("Check how to add API error") +-- create l_page.make (req, "master2/error.tpl") +-- if a_id.is_integer then +-- -- resource not found +-- l_page.set_value ("404", "code") +-- else +-- -- bad request +-- l_page.set_value ("400", "code") +-- end +-- l_page.set_value (req.absolute_script_url (req.path_info), "request") +-- l_page.send_to (res) + end + + +feature -- {NONE} Form data + + extract_data_form (req: WSF_REQUEST): CMS_NODE + -- Extract request form data and build a object + -- Node + do + create Result.make ("", "", "") + if attached {WSF_STRING} req.form_parameter ("title") as l_title then + Result.set_title (l_title.value) + end + end + +end diff --git a/cms/src/modules/node/handler/nodes_handler.e b/cms/src/modules/node/handler/nodes_handler.e new file mode 100644 index 0000000..6b99297 --- /dev/null +++ b/cms/src/modules/node/handler/nodes_handler.e @@ -0,0 +1,52 @@ +note + description: "Summary description for {NODES_HANDLER}." + date: "$Date$" + revision: "$Revision$" + +class + NODES_HANDLER + +inherit + CMS_HANDLER + + WSF_FILTER + + WSF_URI_HANDLER + rename + execute as uri_execute, + new_mapping as new_uri_mapping + end + + WSF_RESOURCE_HANDLER_HELPER + redefine + do_get + end + + REFACTORING_HELPER + +create + make + +feature -- execute + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + execute_next (req, res) + end + + uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + end + +feature -- HTTP Methods + + do_get (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + do + (create {NODES_VIEW_CMS_RESPONSE}.make (req, res, setup,"modules/nodes")).execute + end +end diff --git a/cms/src/modules/node/node_module.e b/cms/src/modules/node/node_module.e new file mode 100644 index 0000000..0470288 --- /dev/null +++ b/cms/src/modules/node/node_module.e @@ -0,0 +1,129 @@ +note + description: "Summary description for {CMS_MODULE}." + date: "$Date$" + revision: "$Revision$" + +class + NODE_MODULE + +inherit + + CMS_MODULE + +create + make + +feature {NONE} -- Initialization + + make (a_config: CMS_SETUP) + do + name := "node" + version := "1.0" + description := "Service to manage content based on 'node'" + package := "core" + config := a_config + setup_router + enable + end + +feature -- Access + + router: WSF_ROUTER + -- Node router. + + config: CMS_SETUP + -- Node configuration. + +feature -- Implementation + + setup_router + -- Setup `router'. + local + fhdl: WSF_FILE_SYSTEM_HANDLER + do + create router.make (5) + configure_api_node + configure_api_nodes + configure_api_node_title + configure_api_node_summary + configure_api_node_content + end + +feature -- Configure Node Resources Routes + + configure_api_node + local + l_node_handler: NODE_HANDLER + l_methods: WSF_REQUEST_METHODS + do + create l_node_handler.make (config) + create l_methods + l_methods.enable_get + l_methods.enable_post + l_methods.enable_put + router.handle_with_request_methods ("/node", l_node_handler, l_methods) + + create l_node_handler.make (config) + create l_methods + l_methods.enable_get + l_methods.enable_post + l_methods.enable_put + l_methods.enable_delete + router.handle_with_request_methods ("/node/{id}", l_node_handler, l_methods) + end + + + configure_api_nodes + local + l_nodes_handler: NODES_HANDLER + l_methods: WSF_REQUEST_METHODS + do + create l_nodes_handler.make (config) + create l_methods + l_methods.enable_get + router.handle_with_request_methods ("/nodes", l_nodes_handler, l_methods) + end + + + configure_api_node_summary + local + l_report_handler: NODE_SUMMARY_HANDLER + l_methods: WSF_REQUEST_METHODS + do + create l_report_handler.make (config) + create l_methods + l_methods.enable_get + l_methods.enable_post + l_methods.enable_put + router.handle_with_request_methods ("/node/{id}/summary", l_report_handler, l_methods) + end + + + configure_api_node_title + local + l_report_handler: NODE_TITLE_HANDLER + l_methods: WSF_REQUEST_METHODS + do + create l_report_handler.make (config) + create l_methods + l_methods.enable_get + l_methods.enable_post + l_methods.enable_put + router.handle_with_request_methods ("/node/{id}/title", l_report_handler, l_methods) + end + + + configure_api_node_content + local + l_report_handler: NODE_CONTENT_HANDLER + l_methods: WSF_REQUEST_METHODS + do + create l_report_handler.make (config) + create l_methods + l_methods.enable_get + l_methods.enable_post + l_methods.enable_put + router.handle_with_request_methods ("/node/{id}/content", l_report_handler, l_methods) + end + +end diff --git a/cms/src/modules/node/response/node_view_cms_response.e b/cms/src/modules/node/response/node_view_cms_response.e new file mode 100644 index 0000000..f115673 --- /dev/null +++ b/cms/src/modules/node/response/node_view_cms_response.e @@ -0,0 +1,37 @@ +note + description: "Summary description for {NODE_VIEW_CMS_RESPONSE}." + date: "$Date$" + revision: "$Revision$" + +class + NODE_VIEW_CMS_RESPONSE + +inherit + + CMS_RESPONSE + redefine + custom_prepare + end + +create + make + +feature -- Generation + + custom_prepare (page: CMS_HTML_PAGE) + do + if attached variables as l_variables then + across l_variables as c loop page.register_variable (c.item, c.key) end + end + end + +feature -- Execution + + process + -- Computed response message. + do + set_title ("List of Nodes") + set_page_title (Void) + end +end + diff --git a/cms/src/modules/node/response/nodes_view_cms_response.e b/cms/src/modules/node/response/nodes_view_cms_response.e new file mode 100644 index 0000000..ecddfe0 --- /dev/null +++ b/cms/src/modules/node/response/nodes_view_cms_response.e @@ -0,0 +1,35 @@ +note + description: "Summary description for {NODE_VIEW_CMS_RESPONSE}." + date: "$Date$" + revision: "$Revision$" + +class + NODES_VIEW_CMS_RESPONSE + +inherit + + CMS_RESPONSE + redefine + custom_prepare + end + +create + make + +feature -- Generation + + custom_prepare (page: CMS_HTML_PAGE) + do + page.register_variable (setup.api_service.nodes, "nodes") + end + +feature -- Execution + + process + -- Computed response message. + do + set_title ("List of Nodes") + set_page_title (Void) + end +end + diff --git a/cms/src/service/cms_api_service.e b/cms/src/service/cms_api_service.e new file mode 100644 index 0000000..547d4c6 --- /dev/null +++ b/cms/src/service/cms_api_service.e @@ -0,0 +1,127 @@ +note + description: "Summary description for {CMS_API_SERVICE}." + date: "$Date$" + revision: "$Revision$" + +class + CMS_API_SERVICE + +inherit + + SHARED_ERROR + REFACTORING_HELPER + + +create make + + +feature -- Initialize + + make (a_storage: CMS_STORAGE) + -- Create the API service with an storege `a_storage'. + do + storage := a_storage + set_successful + ensure + storage_set: storage = a_storage + end + +feature -- Access + + login_valid (l_auth_login, l_auth_password: READABLE_STRING_32): BOOLEAN + local + l_security: SECURITY_PROVIDER + do + Result := storage.is_valid_credential (l_auth_login, l_auth_password) + end + +feature -- Access: Node + + nodes: LIST[CMS_NODE] + -- List of nodes. + do + fixme ("Implementation") + Result := storage.recent_nodes (0, 10) + end + + recent_nodes (a_offset, a_rows: INTEGER): LIST[CMS_NODE] + -- List of the `a_rows' most recent nodes starting from `a_offset'. + do + Result := storage.recent_nodes (a_offset, a_rows) + end + + node (a_id: INTEGER_64): detachable CMS_NODE + -- Node by ID. + do + fixme ("Check preconditions") + Result := storage.node (a_id) + end + + +feature -- Change: Node + + new_node (a_node: CMS_NODE) + -- Add a new node + do + storage.save_node (a_node) + end + + delete_node (a_id: INTEGER_64) + do + storage.delete_node (a_id) + end + + update_node (a_id: like {CMS_USER}.id; a_node: CMS_NODE) + do + storage.update_node (a_id,a_node) + end + + update_node_title (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32) + do + fixme ("Check preconditions") + storage.update_node_title (a_id,a_node_id,a_title) + end + + update_node_summary (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32) + do + fixme ("Check preconditions") + storage.update_node_summary (a_id,a_node_id, a_summary) + end + + update_node_content (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32) + do + fixme ("Check preconditions") + storage.update_node_content (a_id,a_node_id, a_content) + end + + +feature -- Access: User + + user_by_name (a_username: READABLE_STRING_32): detachable CMS_USER + do + Result := storage.user_by_name (a_username) + end +feature -- Change User + + new_user (a_user: CMS_USER) + -- Add a new user `a_user'. + do + if + attached a_user.password as l_password and then + attached a_user.email as l_email + then + storage.save_user (a_user) + else + fixme ("Add error") + end + end + + +feature {NONE} -- Implemenataion + + + storage: CMS_STORAGE + -- Persistence storage + +end + diff --git a/cms/src/service/cms_request_util.e b/cms/src/service/cms_request_util.e new file mode 100644 index 0000000..300d41d --- /dev/null +++ b/cms/src/service/cms_request_util.e @@ -0,0 +1,58 @@ +note + description: "Summary description for {CMS_REQUEST_UTIL}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_REQUEST_UTIL + +inherit + + REFACTORING_HELPER + +feature -- User + + current_user_name (req: WSF_REQUEST): detachable READABLE_STRING_32 + -- Current user name or Void in case of Guest users. + note + EIS: "src=eiffel:?class=AUTHENTICATION_FILTER&feature=execute" + do + if attached {CMS_USER} current_user (req) as l_user then + Result := l_user.name + end + fixme ("Workaround to add nodes!!!") + Result := "admin" -- Workaround + end + + current_user (req: WSF_REQUEST): detachable CMS_USER + -- Current user or Void in case of Guest user. + note + EIS: "eiffel:?class=AUTHENTICATION_FILTER&feature=execute" + do + if attached {CMS_USER} req.execution_variable ("user") as l_user then + Result := l_user + end + end + +feature -- Media Type + + current_media_type (req: WSF_REQUEST): detachable READABLE_STRING_32 + -- Current media type or Void if it's not acceptable. + do + if attached {STRING} req.execution_variable ("media_type") as l_type then + Result := l_type + end + end + +feature -- Absolute Host + + absolute_host (req: WSF_REQUEST; a_path:STRING): STRING + do + Result := req.absolute_script_url (a_path) + if Result.last_index_of ('/', Result.count) = Result.count then + Result.remove_tail (1) + end + end + +end diff --git a/cms/src/service/cms_service.e b/cms/src/service/cms_service.e new file mode 100644 index 0000000..6343ab0 --- /dev/null +++ b/cms/src/service/cms_service.e @@ -0,0 +1,149 @@ +note + description: "[ + This class implements the CMS service + + It could be used to implement the main EWF service, or + even for a specific handler. + ]" + +class + CMS_SERVICE + +inherit + WSF_ROUTED_SKELETON_SERVICE + undefine + requires_proxy + redefine + execute_default + end + + WSF_NO_PROXY_POLICY + + WSF_URI_HELPER_FOR_ROUTED_SERVICE + + WSF_URI_TEMPLATE_HELPER_FOR_ROUTED_SERVICE + + REFACTORING_HELPER + + SHARED_LOGGER + +create + make + +feature {NONE} -- Initialization + + make (a_setup: CMS_SETUP) + do + setup := a_setup + configuration := a_setup.configuration + modules := a_setup.modules + initialize_auth_engine + initialize_mailer + initialize_router + initialize_modules + end + + + + initialize_users + do + to_implement ("To Implement initialize users") + end + + initialize_mailer + do + to_implement ("To Implement mailer") + end + + setup_router + do + configure_api_root + end + + initialize_modules + -- Intialize modules, import router definitions + -- from enabled modules. + do + log.write_debug (generator + ".initialize_modules") + across + modules as m + loop + if m.item.is_enabled then + router.import (m.item.router) + end + end + configure_api_file_handler + end + + initialize_auth_engine + do + to_implement ("To Implement authentication engine") + end + + + configure_api_root + local + l_root_handler: CMS_ROOT_HANDLER + l_methods: WSF_REQUEST_METHODS + do + log.write_debug (generator + ".configure_api_root") + create l_root_handler.make (setup) + create l_methods + l_methods.enable_get + router.handle_with_request_methods ("/", l_root_handler, l_methods) + end + + configure_api_file_handler + local + fhdl: WSF_FILE_SYSTEM_HANDLER + do + log.write_debug (generator + ".configure_api_file_handler") + create fhdl.make_hidden_with_path (setup.layout.www_path) + fhdl.disable_index + fhdl.set_not_found_handler (agent (ia_uri: READABLE_STRING_8; ia_req: WSF_REQUEST; ia_res: WSF_RESPONSE) + do + execute_default (ia_req, ia_res) + end) + router.handle_with_request_methods ("/", fhdl, router.methods_GET) + end + + +feature -- Access + + setup: CMS_SETUP + -- CMS setup. + + configuration: CMS_CONFIGURATION + -- CMS configuration. + -- | Maybe we can compute it (using `setup') instead of using memory. + + modules: LIST [CMS_MODULE] + -- List of possible modules. + -- | Maybe we can compute it (using `setup') instead of using memory. + +feature -- Logging + +feature -- Notification + + +feature -- Execution + + execute_default (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Default request handler if no other are relevant + local + do + fixme ("To Implement") + end + + +note + copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/cms/src/service/handler/cms_handler.e b/cms/src/service/handler/cms_handler.e new file mode 100644 index 0000000..ebe75b7 --- /dev/null +++ b/cms/src/service/handler/cms_handler.e @@ -0,0 +1,36 @@ +note + description: "Summary description for {CMS_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_HANDLER + +inherit + + CMS_REQUEST_UTIL + + SHARED_LOGGER + + REFACTORING_HELPER + +feature {NONE} -- Initialization + + make (a_setup: CMS_SETUP) + do + setup := a_setup + end + +feature -- Setup + + setup: CMS_SETUP + +feature -- API Service + + api_service: CMS_API_SERVICE + do + Result := setup.api_service + end + +end diff --git a/cms/src/service/handler/cms_root_handler.e b/cms/src/service/handler/cms_root_handler.e new file mode 100644 index 0000000..fdb2783 --- /dev/null +++ b/cms/src/service/handler/cms_root_handler.e @@ -0,0 +1,54 @@ +note + description: "Summary description for {CMS_ROOT_HANDLER}." + date: "$Date$" + revision: "$Revision$" + +class + CMS_ROOT_HANDLER + +inherit + + CMS_HANDLER + + WSF_FILTER + + WSF_URI_HANDLER + rename + execute as uri_execute, + new_mapping as new_uri_mapping + end + + WSF_RESOURCE_HANDLER_HELPER + redefine + do_get + end + + REFACTORING_HELPER + +create + make + +feature -- execute + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + execute_next (req, res) + end + + uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + end + +feature -- HTTP Methods + + do_get (req: WSF_REQUEST; res: WSF_RESPONSE) + -- + do + (create {HOME_CMS_RESPONSE}.make (req, res, setup,"layout2")).execute + end + +end diff --git a/cms/src/service/response/cms_generic_response.e b/cms/src/service/response/cms_generic_response.e new file mode 100644 index 0000000..872e852 --- /dev/null +++ b/cms/src/service/response/cms_generic_response.e @@ -0,0 +1,62 @@ +note + description: "Summary description for {CMS_GENERIC_RESPONSE}." + date: "$Date$" + revision: "$Revision$" + +class + CMS_GENERIC_RESPONSE + +feature -- Responses + + new_response_redirect (req: WSF_REQUEST; res: WSF_RESPONSE; a_location: READABLE_STRING_32) + -- Redirect to `a_location' + local + h: HTTP_HEADER + do + create h.make + h.put_content_type_text_html + h.put_current_date + h.put_location (a_location) + res.set_status_code ({HTTP_STATUS_CODE}.see_other) + res.put_header_text (h.string) + end + + new_response_authenticate (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Handle authenticate. + local + h: HTTP_HEADER + do + create h.make + h.put_content_type_text_html + h.put_current_date + h.put_header_key_value ({HTTP_HEADER_NAMES}.header_www_authenticate, "Basic realm=%"CMS-User%"") + res.set_status_code ({HTTP_STATUS_CODE}.unauthorized) + res.put_header_text (h.string) + end + + new_response_denied (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Handle access denied. + local + h: HTTP_HEADER + do + create h.make + h.put_content_type_text_html + h.put_current_date + res.set_status_code ({HTTP_STATUS_CODE}.unauthorized) + res.put_header_text (h.string) + end + + new_response_unauthorized (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Handle not authorized. + local + h: HTTP_HEADER + output: STRING + do + create h.make + h.put_content_type_text_html + h.put_current_date + res.set_status_code ({HTTP_STATUS_CODE}.forbidden) + res.put_header_text (h.string) + end + +end diff --git a/cms/src/service/response/cms_response.e b/cms/src/service/response/cms_response.e new file mode 100644 index 0000000..1f96824 --- /dev/null +++ b/cms/src/service/response/cms_response.e @@ -0,0 +1,177 @@ +note + description: "Generic CMS Response, place to add HOOKS features as collaborators." + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_RESPONSE + +inherit + + CMS_REQUEST_UTIL + + REFACTORING_HELPER + +feature {NONE} -- Initialization + + make (req: WSF_REQUEST; res: WSF_RESPONSE; a_setup: like setup; a_template: like template) + do + status_code := {HTTP_STATUS_CODE}.ok + setup := a_setup + request := req + response := res + template := a_template + create header.make + initialize + end + + initialize + do + get_theme + end + +feature -- Access + + request: WSF_REQUEST + + response: WSF_RESPONSE + + setup: CMS_SETUP + -- Current setup + + status_code: INTEGER + + header: WSF_HEADER + + title: detachable READABLE_STRING_32 + + page_title: detachable READABLE_STRING_32 + -- Page title + + main_content: detachable STRING_8 + + template: READABLE_STRING_32 + -- Current template. + +feature -- Element change + + set_title (t: like title) + do + title := t + set_page_title (t) + end + + set_page_title (t: like page_title) + do + page_title := t + end + + set_main_content (s: like main_content) + do + main_content := s + end + +feature -- Theme + + theme: CMS_THEME + -- Current theme + + get_theme + local + l_info: CMS_THEME_INFORMATION + do + if attached setup.theme_information_location as fn then + create l_info.make (fn) + else + create l_info.make_default + end + if l_info.engine.is_case_insensitive_equal_general ("smarty") then + create {SMARTY_CMS_THEME} theme.make (setup, l_info, template) + else + create {DEFAULT_CMS_THEME} theme.make (setup, l_info) + end + end + +feature -- Generation + + prepare (page: CMS_HTML_PAGE) + do + common_prepare (page) + custom_prepare (page) + end + + common_prepare (page: CMS_HTML_PAGE) + do + fixme ("Fix generacion common") + page.register_variable (request.absolute_script_url (""), "host") + page.register_variable (setup.is_web, "web") + page.register_variable (setup.is_html, "html") + if attached current_user_name (request) as l_user then + page.register_variable (l_user, "user") + end + end + + custom_prepare (page: CMS_HTML_PAGE) + do + end + + +feature -- Custom Variables + + variables: detachable STRING_TABLE[ANY] + -- Custom variables to feed the templates. + + +feature -- Element change: Add custom variables. + + add_variable (a_element: ANY; a_key:READABLE_STRING_32) + local + l_variables: like variables + do + l_variables := variables + if l_variables = Void then + create l_variables.make (5) + variables := l_variables + end + l_variables.force (a_element, a_key) + end + + +feature -- Execution + + execute + do + begin + process + terminate + end + +feature {NONE} -- Execution + + begin + do + end + + process + deferred + end + + frozen terminate + local + cms_page: CMS_HTML_PAGE + page: CMS_HTML_PAGE_RESPONSE + do + create cms_page.make + prepare (cms_page) + create page.make (theme.page_html (cms_page)) + page.set_status_code (status_code) + response.send (page) + on_terminated + end + + on_terminated + do + + end + +end diff --git a/cms/src/service/response/home_cms_response.e b/cms/src/service/response/home_cms_response.e new file mode 100644 index 0000000..b38c0e4 --- /dev/null +++ b/cms/src/service/response/home_cms_response.e @@ -0,0 +1,35 @@ +note + description: "Summary description for {HOME_CMS_RESPONSE}." + date: "$Date$" + revision: "$Revision$" + +class + HOME_CMS_RESPONSE + +inherit + + CMS_RESPONSE + redefine + custom_prepare + end + +create + make + +feature -- Generation + + custom_prepare (page: CMS_HTML_PAGE) + do + page.register_variable (setup.api_service.recent_nodes (0, 5), "nodes") + end + +feature -- Execution + + process + -- Computed response message. + do + set_title ("Home") + set_page_title (Void) + end +end + diff --git a/cms/src/theme/cms_html_page_response.e b/cms/src/theme/cms_html_page_response.e new file mode 100644 index 0000000..97af15f --- /dev/null +++ b/cms/src/theme/cms_html_page_response.e @@ -0,0 +1,77 @@ +note + description: "Summary description for {CMS_HTML_PAGE_RESPONSE}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + CMS_HTML_PAGE_RESPONSE + +inherit + WSF_RESPONSE_MESSAGE + +create + make + +feature {NONE} -- Initialization + + make (a_html: like html) + do + html := a_html + status_code := {HTTP_STATUS_CODE}.ok + create header.make + header.put_content_type_text_html + end + +feature -- Status + + status_code: INTEGER + +feature -- Header + + header: HTTP_HEADER + +feature -- Html access + + html: STRING + +feature -- Element change + + set_status_code (c: like status_code) + do + status_code := c + end + +feature {WSF_RESPONSE} -- Output + + send_to (res: WSF_RESPONSE) + local + h: like header + s: STRING_8 + do + h := header + res.set_status_code (status_code) + s := html + + if not h.has_content_length then + h.put_content_length (s.count) + end + if not h.has_content_type then + h.put_content_type_text_html + end + res.put_header_text (h.string) + res.put_string (s) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end + diff --git a/cms/src/theme/cms_html_template.e b/cms/src/theme/cms_html_template.e new file mode 100644 index 0000000..86a93f5 --- /dev/null +++ b/cms/src/theme/cms_html_template.e @@ -0,0 +1,13 @@ +note + description: "Summary description for {WSF_CMS_HTML_TEMPLATE}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_HTML_TEMPLATE + +inherit + CMS_TEMPLATE + +end diff --git a/cms/src/theme/cms_page_template.e b/cms/src/theme/cms_page_template.e new file mode 100644 index 0000000..74c3664 --- /dev/null +++ b/cms/src/theme/cms_page_template.e @@ -0,0 +1,12 @@ +note + description: "Summary description for {CMS_PAGE_TEMPLATE}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_PAGE_TEMPLATE + +inherit + CMS_TEMPLATE +end diff --git a/cms/src/theme/cms_template.e b/cms/src/theme/cms_template.e new file mode 100644 index 0000000..58eb0f0 --- /dev/null +++ b/cms/src/theme/cms_template.e @@ -0,0 +1,37 @@ +note + description: "Summary description for {WSF_CMS_PAGE_TEMPLATE}." + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_TEMPLATE + +feature -- Access + + theme: CMS_THEME + deferred + end + + variables: STRING_TABLE [detachable ANY] + deferred + end + + prepare (page: CMS_HTML_PAGE) + deferred + end + + to_html (page: CMS_HTML_PAGE): STRING + deferred + end + +note + copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/cms/src/theme/cms_theme.e b/cms/src/theme/cms_theme.e new file mode 100644 index 0000000..4557a61 --- /dev/null +++ b/cms/src/theme/cms_theme.e @@ -0,0 +1,48 @@ +note + description: "Summary description for {WSF_CMS_THEME}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_THEME + +feature {NONE} -- Access + + setup: CMS_SETUP + +feature -- Access + + name: STRING + deferred + end + + regions: ARRAY [STRING] + deferred + end + + page_template: CMS_TEMPLATE + deferred + end + +feature -- Conversion + + page_html (page: CMS_HTML_PAGE): STRING_8 + -- Render `page' as html. + deferred + end + +feature {NONE} -- Implementation + + +note + copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/cms/src/theme/cms_theme_information.e b/cms/src/theme/cms_theme_information.e new file mode 100644 index 0000000..ee0800a --- /dev/null +++ b/cms/src/theme/cms_theme_information.e @@ -0,0 +1,135 @@ +note + description: "Summary description for {CMS_THEME_INFORMATION}." + date: "$Date$" + revision: "$Revision$" + +class + CMS_THEME_INFORMATION + +create + make, + make_default + +feature {NONE} -- Initialization + + make_default + do + engine := {STRING_32} "default" + create items.make_caseless (1) + create regions.make (5) + across + (<<"header", "content", "footer", "first_sidebar", "second_sidebar">>) as ic + loop + regions.force (ic.item, ic.item) + end + end + + make (fn: PATH) + local + f: PLAIN_TEXT_FILE + s: STRING_8 + h,k: STRING_8 + v: STRING_32 + i: INTEGER + utf: UTF_CONVERTER + l_engine: detachable READABLE_STRING_32 + done: BOOLEAN + do + make_default + create f.make_with_path (fn) + if f.exists and then f.is_access_readable then + f.open_read + from + until + done or f.exhausted or f.end_of_file + loop + f.read_line_thread_aware + s := f.last_string + s.left_adjust + if + s.is_empty + or else s.starts_with_general (";") + or else s.starts_with_general ("#") + or else s.starts_with_general ("--") + then + -- Ignore + else + i := s.index_of ('=', 1) + if i > 0 then + h := s.substring (1, i - 1) + h.left_adjust + h.right_adjust + if h.is_case_insensitive_equal_general ("engine") then + s.remove_head (i) + s.right_adjust + v := utf.utf_8_string_8_to_string_32 (s) + l_engine := v + elseif h.starts_with_general ("regions[") and h[h.count] = ']' then + s.remove_head (i) + s.right_adjust + v := utf.utf_8_string_8_to_string_32 (s) + i := h.index_of ('[', 1) + k := h.substring (i + 1, h.count - 1) + k.left_adjust + k.right_adjust + if k.starts_with_general ("-") then + --| If name is prefixed by "-" + --| remove the related region + --| If name is "-*", clear all regions. + if k.is_case_insensitive_equal_general ("-*") then + regions.wipe_out + else + k.remove_head (1) + regions.remove (k) + end + else + regions.force (v, k) + end + else + s.remove_head (i) + s.right_adjust + v := utf.utf_8_string_8_to_string_32 (s) + end + items.force (v, h) + end + end + end + f.close + end + if l_engine /= Void and then not l_engine.is_empty then + engine := l_engine + end + end + +feature -- Access + + engine: STRING_32 + -- Template engine. + --| Could be: default, smarty, ... + + regions: STRING_TABLE [READABLE_STRING_GENERAL] + -- Regions available in this theme + + item (k: READABLE_STRING_GENERAL): detachable STRING_32 + -- Item associated with name `k' if any. + do + Result := items[k] + end + + items: STRING_TABLE [STRING_32] + -- Items indexed by key name. + +invariant + engine_set: not engine.is_empty + +note + copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/cms/src/theme/default_cms_template.e b/cms/src/theme/default_cms_template.e new file mode 100644 index 0000000..e919318 --- /dev/null +++ b/cms/src/theme/default_cms_template.e @@ -0,0 +1,75 @@ +note + description: "Summary description for {DEFAULT_CMS_TEMPLATE}." + date: "$Date$" + revision: "$Revision$" + +deferred class + DEFAULT_CMS_TEMPLATE + +inherit + CMS_TEMPLATE + +feature {NONE} -- Implementation + + apply_template_engine (s: STRING_8) + local + p,n: INTEGER + k: STRING + sv: detachable STRING + do + from + n := s.count + p := 1 + until + p = 0 + loop + p := s.index_of ('$', p) + if p > 0 then + k := next_identifier (s, p + 1) + s.remove_substring (p, p + k.count) + sv := Void + if attached variables.item (k) as l_value then + + if attached {STRING_8} l_value as s8 then + sv := s8 + elseif attached {STRING_32} l_value as s32 then + sv := s32.as_string_8 -- FIXME: use html encoder + else + sv := l_value.out + end + s.insert_string (sv, p) + p := p + sv.count + else + debug + s.insert_string ("$" + k, p) + end + end + end + end + end + + next_identifier (s: STRING; a_index: INTEGER): STRING + local + i: INTEGER + do + from + i := a_index + until + not (s[i].is_alpha_numeric or s[i] = '_' or s[i] = '.') + loop + i := i + 1 + end + Result := s.substring (a_index, i - 1) + end + +note + copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/cms/src/theme/default_theme/default_cms_html_template.e b/cms/src/theme/default_theme/default_cms_html_template.e new file mode 100644 index 0000000..3667e2b --- /dev/null +++ b/cms/src/theme/default_theme/default_cms_html_template.e @@ -0,0 +1,100 @@ +note + description: "Summary description for {CMS_HTML_TEMPLATE}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + DEFAULT_CMS_HTML_TEMPLATE + +inherit + CMS_HTML_TEMPLATE + + DEFAULT_CMS_TEMPLATE + +create + make + +feature {NONE} -- Initialization + + make (t: DEFAULT_CMS_THEME) + do + theme := t + create variables.make (0) + end + + variables: STRING_TABLE [detachable ANY] + +feature -- Access + + register (v: STRING_8; k: STRING_8) + do + variables.force (v, k) + end + + theme: DEFAULT_CMS_THEME + + prepare (page: CMS_HTML_PAGE) + do + variables.make (10) + + across + page.variables as ic + loop + variables.force (ic.item, ic.key) + end + + if attached page.title as l_title then + variables.force (l_title, "title") + variables.force (l_title, "head_title") + else + variables.force ("", "title") + variables.force ("", "head_title") + end + + variables.force (page.language, "language") + variables.force (page.head_lines_to_string, "head_lines") + end + + to_html (page: CMS_HTML_PAGE): STRING + do + -- Process html generation + create Result.make_from_string (template) + apply_template_engine (Result) + end + +feature {NONE} -- Implementation + + template: STRING + once + Result := "[ + + + + $head + $head_title + $styles + $scripts + $head_lines + + + $page_top + $page + $page_bottom + + + ]" + end + + +note + copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/cms/src/theme/default_theme/default_cms_page_template.e b/cms/src/theme/default_theme/default_cms_page_template.e new file mode 100644 index 0000000..0e4ceab --- /dev/null +++ b/cms/src/theme/default_theme/default_cms_page_template.e @@ -0,0 +1,102 @@ +note + description: "Summary description for {CMS_PAGE_TEMPLATE}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + DEFAULT_CMS_PAGE_TEMPLATE + +inherit + CMS_PAGE_TEMPLATE + + DEFAULT_CMS_TEMPLATE + +create + make + +feature {NONE} -- Initialization + + make (t: DEFAULT_CMS_THEME) + do + theme := t + create variables.make (0) + end + + variables: STRING_TABLE [detachable ANY] + +feature -- Access + + theme: DEFAULT_CMS_THEME + + prepare (page: CMS_HTML_PAGE) + do + variables.make (10) + + across + page.variables as ic + loop + variables.force (ic.item, ic.key) + end + + if attached page.title as l_title then + variables.force (l_title, "title") + else + variables.force ("", "title") + end + across + theme.regions as r + loop + variables.force (page.region (r.item), r.item) + end + end + + to_html (page: CMS_HTML_PAGE): STRING + do + -- Process html generation + create Result.make_from_string (template) + apply_template_engine (Result) + end + +feature -- Registration + + register (v: STRING_8; k: STRING_8) + do + variables.force (v, k) + end + +feature {NONE} -- Implementation + + template: STRING + once + Result := "[ +
+
+ +
+
+ +
$content
+ +
+
+ +
+
+ ]" + end + + +note + copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/cms/src/theme/default_theme/default_cms_theme.e b/cms/src/theme/default_theme/default_cms_theme.e new file mode 100644 index 0000000..dcf4950 --- /dev/null +++ b/cms/src/theme/default_theme/default_cms_theme.e @@ -0,0 +1,96 @@ +note + description: "Summary description for {CMS_THEME}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + DEFAULT_CMS_THEME + +inherit + CMS_THEME + +create + make + +feature {NONE} -- Initialization + + make (a_setup: like setup; a_info: like information) + do + setup := a_setup + information := a_info + end + + information: CMS_THEME_INFORMATION + +feature -- Access + + name: STRING = "CMS" + + regions: ARRAY [STRING] + once + Result := <<"header", "content", "footer", "first_sidebar", "second_sidebar">> + end + + html_template: DEFAULT_CMS_HTML_TEMPLATE + local + tpl: like internal_html_template + do + tpl := internal_html_template + if tpl = Void then + create tpl.make (Current) + internal_html_template := tpl + end + Result := tpl + end + + page_template: DEFAULT_CMS_PAGE_TEMPLATE + local + tpl: like internal_page_template + do + tpl := internal_page_template + if tpl = Void then + create tpl.make (Current) + internal_page_template := tpl + end + Result := tpl + end + +feature -- Conversion + + prepare (page: CMS_HTML_PAGE) + do +-- page.add_style (url ("/theme/style.css", Void), Void) + end + + page_html (page: CMS_HTML_PAGE): STRING_8 + local + l_content: STRING_8 + do + prepare (page) + page_template.prepare (page) + l_content := page_template.to_html (page) + html_template.prepare (page) + html_template.register (l_content, "page") + Result := html_template.to_html (page) + end + +feature {NONE} -- Internal + + internal_page_template: detachable like page_template + + internal_html_template: detachable like html_template + +invariant + attached internal_page_template as inv_p implies inv_p.theme = Current +note + copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/cms/src/theme/smarty_theme/smarty_cms_page_template.e b/cms/src/theme/smarty_theme/smarty_cms_page_template.e new file mode 100644 index 0000000..427c186 --- /dev/null +++ b/cms/src/theme/smarty_theme/smarty_cms_page_template.e @@ -0,0 +1,134 @@ +note + description: "Summary description for {CMS_PAGE_TEMPLATE}." + date: "$Date$" + revision: "$Revision$" + +class + SMARTY_CMS_PAGE_TEMPLATE + +inherit + CMS_PAGE_TEMPLATE + + SHARED_TEMPLATE_CONTEXT + +create + make + +feature {NONE} -- Initialization + + make (tpl: READABLE_STRING_GENERAL; t: SMARTY_CMS_THEME) + do + theme := t + create variables.make (0) + template_name := tpl + end + + variables: STRING_TABLE [detachable ANY] + +feature -- Access + + template_name: READABLE_STRING_GENERAL + + theme: SMARTY_CMS_THEME + + prepare (page: CMS_HTML_PAGE) + do + variables.make (10) + + across + page.variables as ic + loop + variables.force (ic.item, ic.key) + end + + if attached page.title as l_title then + variables.force (l_title, "title") + variables.force (l_title, "head_title") + else + variables.force ("", "title") + variables.force ("", "head_title") + end + + variables.force (page.language, "language") + variables.force (page.head_lines_to_string, "head_lines") + + across + theme.regions as r + loop + variables.force (page.region (r.item), r.item) + end + end + + to_html (page: CMS_HTML_PAGE): STRING + local + tpl: detachable TEMPLATE_FILE + ut: FILE_UTILITIES + p: detachable PATH + n: STRING_32 + do + -- Process html generation + template_context.set_template_folder (theme.templates_directory) + template_context.disable_verbose + debug ("smarty") + template_context.enable_verbose + end + p := template_context.template_folder + if p = Void then + create p.make_current + end + if attached page.type as l_page_type then + create n.make_from_string_general (l_page_type) + n.append_character ('-') + n.append_string_general (template_name) + n.append_string_general (".tpl") + if ut.file_path_exists (p.extended (n)) then + create tpl.make_from_file (n) + end + end + if tpl = Void then + create n.make_from_string_general (template_name) + n.append_string_general (".tpl") + if ut.file_path_exists (p.extended (n)) then + create tpl.make_from_file (n) + end + end + if tpl /= Void then + across + variables as ic + loop + tpl.add_value (ic.item, ic.key) + end + + debug ("cms") + template_context.enable_verbose + end + tpl.analyze + tpl.get_output + if attached tpl.output as l_output then + Result := l_output + else + create Result.make_from_string ("ERROR: template issue.") + end + else + create Result.make_from_string ("ERROR: template issue.") + end + end + +feature -- Registration + + register (v: STRING_8; k: STRING_8) + do + variables.force (v, k) + end + +note + copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/cms/src/theme/smarty_theme/smarty_cms_theme.e b/cms/src/theme/smarty_theme/smarty_cms_theme.e new file mode 100644 index 0000000..f315f57 --- /dev/null +++ b/cms/src/theme/smarty_theme/smarty_cms_theme.e @@ -0,0 +1,104 @@ +note + description: "Summary description for {SMARTY_CMS_THEME}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SMARTY_CMS_THEME + +inherit + CMS_THEME + +create + make + +feature {NONE} -- Initialization + + make (a_setup: like setup; a_info: like information; a_template: like template) + do + setup := a_setup + information := a_info + template := a_template + if attached a_info.item ("template_dir") as s then + templates_directory := a_setup.theme_location.extended (s) + else + templates_directory := a_setup.theme_location + end + ensure + setup_set: setup = a_setup + information_set: information = a_info + template_set: template = a_template + end + +feature -- Access + + name: STRING = "smarty-CMS" + + template: STRING; + + templates_directory: PATH + + information: CMS_THEME_INFORMATION + + regions: ARRAY [STRING] + local + i: INTEGER + utf: UTF_CONVERTER + once + if attached information.regions as tb and then not tb.is_empty then + i := 1 + create Result.make_filled ("", i, i + tb.count - 1) + across + tb as ic + loop + Result.force (utf.utf_32_string_to_utf_8_string_8 (ic.key), i) -- NOTE: UTF-8 encoded ! + i := i + 1 + end + else + Result := <<"header", "content", "footer", "first_sidebar", "second_sidebar">> + end + end + + page_template: SMARTY_CMS_PAGE_TEMPLATE + local + tpl: like internal_page_template + do + tpl := internal_page_template + if tpl = Void then + create tpl.make (template, Current) + internal_page_template := tpl + end + Result := tpl + end + +feature -- Conversion + + prepare (page: CMS_HTML_PAGE) + do + end + + page_html (page: CMS_HTML_PAGE): STRING_8 + do + prepare (page) + page_template.prepare (page) + Result := page_template.to_html (page) + end + +feature {NONE} -- Internal + + internal_page_template: detachable like page_template + +invariant + attached internal_page_template as inv_p implies inv_p.theme = Current +note + copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/examples/Readme.md b/examples/Readme.md new file mode 100644 index 0000000..beadd23 --- /dev/null +++ b/examples/Readme.md @@ -0,0 +1,4 @@ +Examples CMS: examples + +api: API is a simple example showing how to build a custom CMS using EWF. +roc_api: api build using a CMS library using modules, themes, etc. \ No newline at end of file diff --git a/Readme.txt b/examples/api/Readme.txt similarity index 100% rename from Readme.txt rename to examples/api/Readme.txt diff --git a/api/launcher/any/application_launcher.e b/examples/api/launcher/any/application_launcher.e similarity index 100% rename from api/launcher/any/application_launcher.e rename to examples/api/launcher/any/application_launcher.e diff --git a/api/launcher/any/application_launcher_i.e b/examples/api/launcher/any/application_launcher_i.e similarity index 100% rename from api/launcher/any/application_launcher_i.e rename to examples/api/launcher/any/application_launcher_i.e diff --git a/api/launcher/default/application_launcher.e b/examples/api/launcher/default/application_launcher.e similarity index 100% rename from api/launcher/default/application_launcher.e rename to examples/api/launcher/default/application_launcher.e diff --git a/api/launcher/default/application_launcher_i.e b/examples/api/launcher/default/application_launcher_i.e similarity index 100% rename from api/launcher/default/application_launcher_i.e rename to examples/api/launcher/default/application_launcher_i.e diff --git a/api/roc.ini b/examples/api/roc.ini similarity index 56% rename from api/roc.ini rename to examples/api/roc.ini index 70c3255..17eb967 100644 --- a/api/roc.ini +++ b/examples/api/roc.ini @@ -1,2 +1,2 @@ -port=7070 +port=8088 #verbose=true \ No newline at end of file diff --git a/api/roc_api.ecf b/examples/api/roc_api.ecf similarity index 90% rename from api/roc_api.ecf rename to examples/api/roc_api.ecf index ab56bd2..adf512d 100644 --- a/api/roc_api.ecf +++ b/examples/api/roc_api.ecf @@ -1,5 +1,5 @@  - + /EIFGENs$ @@ -16,12 +16,12 @@ - + - + @@ -29,7 +29,7 @@ - + @@ -37,19 +37,19 @@ - + - + - + @@ -60,7 +60,7 @@ - - + diff --git a/examples/api/site/config/application_configuration.json b/examples/api/site/config/application_configuration.json new file mode 100644 index 0000000..793f8ef --- /dev/null +++ b/examples/api/site/config/application_configuration.json @@ -0,0 +1,32 @@ +{ + "database": { + "datasource": { + "driver": "MySQL", + "environment": "development" + }, + "environments": { + "test": { + "connection_string":"Server=localhost;Port=3306;Database=cms_dev;Uid=root;Pwd=;" + }, + "development": { + "connection_string":"Server=localhost;Port=3306;Database=cms_dev;Uid=root;Pwd=;" + }, + "production": { + "connection_string":"" + } + } + }, + "smtp": { + "server": "localhost" + }, + "logger": { + "level":"debug", + "backup_count":"4" + }, + "server": { + "mode":"html" + } + +} + + \ No newline at end of file diff --git a/api/site/www/static/css/bootstrap.css b/examples/api/site/www/static/css/bootstrap.css similarity index 100% rename from api/site/www/static/css/bootstrap.css rename to examples/api/site/www/static/css/bootstrap.css diff --git a/api/site/www/static/css/dashboard.css b/examples/api/site/www/static/css/dashboard.css similarity index 100% rename from api/site/www/static/css/dashboard.css rename to examples/api/site/www/static/css/dashboard.css diff --git a/api/site/www/static/images/ajax-loader.gif b/examples/api/site/www/static/images/ajax-loader.gif similarity index 100% rename from api/site/www/static/images/ajax-loader.gif rename to examples/api/site/www/static/images/ajax-loader.gif diff --git a/api/site/www/static/images/favicon.ico b/examples/api/site/www/static/images/favicon.ico similarity index 100% rename from api/site/www/static/images/favicon.ico rename to examples/api/site/www/static/images/favicon.ico diff --git a/api/site/www/static/js/roc.js b/examples/api/site/www/static/js/roc.js similarity index 100% rename from api/site/www/static/js/roc.js rename to examples/api/site/www/static/js/roc.js diff --git a/api/site/www/template/html/layout2.tpl b/examples/api/site/www/template/html/layout2.tpl similarity index 100% rename from api/site/www/template/html/layout2.tpl rename to examples/api/site/www/template/html/layout2.tpl diff --git a/api/site/www/template/html/master2/content.tpl b/examples/api/site/www/template/html/master2/content.tpl similarity index 100% rename from api/site/www/template/html/master2/content.tpl rename to examples/api/site/www/template/html/master2/content.tpl diff --git a/api/site/www/template/html/master2/error.tpl b/examples/api/site/www/template/html/master2/error.tpl similarity index 100% rename from api/site/www/template/html/master2/error.tpl rename to examples/api/site/www/template/html/master2/error.tpl diff --git a/api/site/www/template/html/master2/footer.tpl b/examples/api/site/www/template/html/master2/footer.tpl similarity index 100% rename from api/site/www/template/html/master2/footer.tpl rename to examples/api/site/www/template/html/master2/footer.tpl diff --git a/api/site/www/template/html/master2/head.tpl b/examples/api/site/www/template/html/master2/head.tpl similarity index 100% rename from api/site/www/template/html/master2/head.tpl rename to examples/api/site/www/template/html/master2/head.tpl diff --git a/api/site/www/template/html/master2/header.tpl b/examples/api/site/www/template/html/master2/header.tpl similarity index 100% rename from api/site/www/template/html/master2/header.tpl rename to examples/api/site/www/template/html/master2/header.tpl diff --git a/api/site/www/template/html/master2/logoff.tpl b/examples/api/site/www/template/html/master2/logoff.tpl similarity index 100% rename from api/site/www/template/html/master2/logoff.tpl rename to examples/api/site/www/template/html/master2/logoff.tpl diff --git a/api/site/www/template/html/master2/main_navigation.tpl b/examples/api/site/www/template/html/master2/main_navigation.tpl similarity index 100% rename from api/site/www/template/html/master2/main_navigation.tpl rename to examples/api/site/www/template/html/master2/main_navigation.tpl diff --git a/api/site/www/template/html/master2/optional_enhancement_js.tpl b/examples/api/site/www/template/html/master2/optional_enhancement_js.tpl similarity index 100% rename from api/site/www/template/html/master2/optional_enhancement_js.tpl rename to examples/api/site/www/template/html/master2/optional_enhancement_js.tpl diff --git a/api/site/www/template/html/master2/optional_styling_css.tpl b/examples/api/site/www/template/html/master2/optional_styling_css.tpl similarity index 100% rename from api/site/www/template/html/master2/optional_styling_css.tpl rename to examples/api/site/www/template/html/master2/optional_styling_css.tpl diff --git a/api/site/www/template/html/master2/site_navigation.tpl b/examples/api/site/www/template/html/master2/site_navigation.tpl similarity index 100% rename from api/site/www/template/html/master2/site_navigation.tpl rename to examples/api/site/www/template/html/master2/site_navigation.tpl diff --git a/api/site/www/template/html/modules/navigation.tpl b/examples/api/site/www/template/html/modules/navigation.tpl similarity index 100% rename from api/site/www/template/html/modules/navigation.tpl rename to examples/api/site/www/template/html/modules/navigation.tpl diff --git a/api/site/www/template/html/modules/node.tpl b/examples/api/site/www/template/html/modules/node.tpl similarity index 100% rename from api/site/www/template/html/modules/node.tpl rename to examples/api/site/www/template/html/modules/node.tpl diff --git a/api/site/www/template/html/modules/node_content.tpl b/examples/api/site/www/template/html/modules/node_content.tpl similarity index 100% rename from api/site/www/template/html/modules/node_content.tpl rename to examples/api/site/www/template/html/modules/node_content.tpl diff --git a/api/site/www/template/html/modules/node_summary.tpl b/examples/api/site/www/template/html/modules/node_summary.tpl similarity index 100% rename from api/site/www/template/html/modules/node_summary.tpl rename to examples/api/site/www/template/html/modules/node_summary.tpl diff --git a/api/site/www/template/html/modules/node_title.tpl b/examples/api/site/www/template/html/modules/node_title.tpl similarity index 100% rename from api/site/www/template/html/modules/node_title.tpl rename to examples/api/site/www/template/html/modules/node_title.tpl diff --git a/api/site/www/template/html/modules/nodes.tpl b/examples/api/site/www/template/html/modules/nodes.tpl similarity index 100% rename from api/site/www/template/html/modules/nodes.tpl rename to examples/api/site/www/template/html/modules/nodes.tpl diff --git a/api/site/www/template/html/modules/register.tpl b/examples/api/site/www/template/html/modules/register.tpl similarity index 100% rename from api/site/www/template/html/modules/register.tpl rename to examples/api/site/www/template/html/modules/register.tpl diff --git a/api/src/configuration/application_constants.e b/examples/api/src/configuration/application_constants.e similarity index 100% rename from api/src/configuration/application_constants.e rename to examples/api/src/configuration/application_constants.e diff --git a/api/src/configuration/configuration_factory.e b/examples/api/src/configuration/configuration_factory.e similarity index 100% rename from api/src/configuration/configuration_factory.e rename to examples/api/src/configuration/configuration_factory.e diff --git a/api/src/configuration/roc_json_configuration.e b/examples/api/src/configuration/roc_json_configuration.e similarity index 100% rename from api/src/configuration/roc_json_configuration.e rename to examples/api/src/configuration/roc_json_configuration.e diff --git a/api/src/representation/common/template_shared.e b/examples/api/src/representation/common/template_shared.e similarity index 100% rename from api/src/representation/common/template_shared.e rename to examples/api/src/representation/common/template_shared.e diff --git a/api/src/representation/roc_response.e b/examples/api/src/representation/roc_response.e similarity index 100% rename from api/src/representation/roc_response.e rename to examples/api/src/representation/roc_response.e diff --git a/api/src/representation/roc_template_page.e b/examples/api/src/representation/roc_template_page.e similarity index 100% rename from api/src/representation/roc_template_page.e rename to examples/api/src/representation/roc_template_page.e diff --git a/api/src/roc_abstract_api.e b/examples/api/src/roc_abstract_api.e similarity index 100% rename from api/src/roc_abstract_api.e rename to examples/api/src/roc_abstract_api.e diff --git a/api/src/roc_config.e b/examples/api/src/roc_config.e similarity index 100% rename from api/src/roc_config.e rename to examples/api/src/roc_config.e diff --git a/api/src/roc_server.e b/examples/api/src/roc_server.e similarity index 100% rename from api/src/roc_server.e rename to examples/api/src/roc_server.e diff --git a/api/src/service/filter/authentication_filter.e b/examples/api/src/service/filter/authentication_filter.e similarity index 100% rename from api/src/service/filter/authentication_filter.e rename to examples/api/src/service/filter/authentication_filter.e diff --git a/api/src/service/filter/cors_filter.e b/examples/api/src/service/filter/cors_filter.e similarity index 100% rename from api/src/service/filter/cors_filter.e rename to examples/api/src/service/filter/cors_filter.e diff --git a/api/src/service/filter/error_filter.e b/examples/api/src/service/filter/error_filter.e similarity index 100% rename from api/src/service/filter/error_filter.e rename to examples/api/src/service/filter/error_filter.e diff --git a/api/src/service/filter/logger_filter.e b/examples/api/src/service/filter/logger_filter.e similarity index 100% rename from api/src/service/filter/logger_filter.e rename to examples/api/src/service/filter/logger_filter.e diff --git a/api/src/service/handler/app_abstract_handler.e b/examples/api/src/service/handler/app_abstract_handler.e similarity index 100% rename from api/src/service/handler/app_abstract_handler.e rename to examples/api/src/service/handler/app_abstract_handler.e diff --git a/api/src/service/handler/app_handler.e b/examples/api/src/service/handler/app_handler.e similarity index 100% rename from api/src/service/handler/app_handler.e rename to examples/api/src/service/handler/app_handler.e diff --git a/api/src/service/handler/navigation_handler.e b/examples/api/src/service/handler/navigation_handler.e similarity index 100% rename from api/src/service/handler/navigation_handler.e rename to examples/api/src/service/handler/navigation_handler.e diff --git a/api/src/service/handler/node_content_handler.e b/examples/api/src/service/handler/node_content_handler.e similarity index 100% rename from api/src/service/handler/node_content_handler.e rename to examples/api/src/service/handler/node_content_handler.e diff --git a/api/src/service/handler/node_handler.e b/examples/api/src/service/handler/node_handler.e similarity index 100% rename from api/src/service/handler/node_handler.e rename to examples/api/src/service/handler/node_handler.e diff --git a/api/src/service/handler/node_summary_handler.e b/examples/api/src/service/handler/node_summary_handler.e similarity index 100% rename from api/src/service/handler/node_summary_handler.e rename to examples/api/src/service/handler/node_summary_handler.e diff --git a/api/src/service/handler/node_title_handler.e b/examples/api/src/service/handler/node_title_handler.e similarity index 100% rename from api/src/service/handler/node_title_handler.e rename to examples/api/src/service/handler/node_title_handler.e diff --git a/api/src/service/handler/nodes_handler.e b/examples/api/src/service/handler/nodes_handler.e similarity index 100% rename from api/src/service/handler/nodes_handler.e rename to examples/api/src/service/handler/nodes_handler.e diff --git a/api/src/service/handler/roc_login_handler.e b/examples/api/src/service/handler/roc_login_handler.e similarity index 100% rename from api/src/service/handler/roc_login_handler.e rename to examples/api/src/service/handler/roc_login_handler.e diff --git a/api/src/service/handler/roc_logoff_handler.e b/examples/api/src/service/handler/roc_logoff_handler.e similarity index 100% rename from api/src/service/handler/roc_logoff_handler.e rename to examples/api/src/service/handler/roc_logoff_handler.e diff --git a/api/src/service/handler/roc_root_handler.e b/examples/api/src/service/handler/roc_root_handler.e similarity index 100% rename from api/src/service/handler/roc_root_handler.e rename to examples/api/src/service/handler/roc_root_handler.e diff --git a/api/src/service/handler/user_handler.e b/examples/api/src/service/handler/user_handler.e similarity index 100% rename from api/src/service/handler/user_handler.e rename to examples/api/src/service/handler/user_handler.e diff --git a/api/src/service/roc_api_service.e b/examples/api/src/service/roc_api_service.e similarity index 100% rename from api/src/service/roc_api_service.e rename to examples/api/src/service/roc_api_service.e diff --git a/api/src/service/roc_email_service.e b/examples/api/src/service/roc_email_service.e similarity index 100% rename from api/src/service/roc_email_service.e rename to examples/api/src/service/roc_email_service.e diff --git a/api/src/service/roc_rest_api.e b/examples/api/src/service/roc_rest_api.e similarity index 100% rename from api/src/service/roc_rest_api.e rename to examples/api/src/service/roc_rest_api.e diff --git a/api/src/service/shared_conneg_helper.e b/examples/api/src/service/shared_conneg_helper.e similarity index 100% rename from api/src/service/shared_conneg_helper.e rename to examples/api/src/service/shared_conneg_helper.e diff --git a/api/src/validator/roc_input_validator.e b/examples/api/src/validator/roc_input_validator.e similarity index 100% rename from api/src/validator/roc_input_validator.e rename to examples/api/src/validator/roc_input_validator.e diff --git a/examples/roc_api/Readme.md b/examples/roc_api/Readme.md new file mode 100644 index 0000000..e69de29 diff --git a/examples/roc_api/launcher/any/application_launcher.e b/examples/roc_api/launcher/any/application_launcher.e new file mode 100644 index 0000000..0ef505c --- /dev/null +++ b/examples/roc_api/launcher/any/application_launcher.e @@ -0,0 +1,19 @@ +note + description: "[ + Effective class for APPLICATION_LAUNCHER_I + + You can put modification in this class + ]" + date: "$Date: 2013-06-12 13:55:42 +0200 (mer., 12 juin 2013) $" + revision: "$Revision: 36 $" + +class + APPLICATION_LAUNCHER + +inherit + APPLICATION_LAUNCHER_I + +feature -- Custom + +end + diff --git a/examples/roc_api/launcher/any/application_launcher_i.e b/examples/roc_api/launcher/any/application_launcher_i.e new file mode 100644 index 0000000..0744c80 --- /dev/null +++ b/examples/roc_api/launcher/any/application_launcher_i.e @@ -0,0 +1,102 @@ +note + description: "[ + Specific application launcher + + DO NOT EDIT THIS CLASS + + you can customize APPLICATION_LAUNCHER + ]" + date: "$Date: 2013-06-12 13:55:42 +0200 (mer., 12 juin 2013) $" + revision: "$Revision: 36 $" + +deferred class + APPLICATION_LAUNCHER_I + +inherit + SHARED_EXECUTION_ENVIRONMENT + +feature -- Execution + + launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + local + nature: like launcher_nature + do + nature := launcher_nature + if nature = Void or else nature = nature_nino then + launch_nino (a_service, opts) + elseif nature = nature_cgi then + launch_cgi (a_service, opts) + elseif nature = nature_libfcgi then + launch_libfcgi (a_service, opts) + else + -- bye bye + (create {EXCEPTIONS}).die (-1) + end + end + +feature {NONE} -- Access + + launcher_nature: detachable READABLE_STRING_8 + -- Initialize the launcher nature + -- either cgi, libfcgi, or nino. + --| We could extend with more connector if needed. + --| and we could use WSF_DEFAULT_SERVICE_LAUNCHER to configure this at compilation time. + local + p: PATH + l_entry_name: READABLE_STRING_32 + ext: detachable READABLE_STRING_32 + do + create p.make_from_string (execution_environment.arguments.command_name) + if attached p.entry as l_entry then + ext := l_entry.extension + end + if ext /= Void then + if ext.same_string (nature_nino) then + Result := nature_nino + end + if ext.same_string (nature_cgi) then + Result := nature_cgi + end + if ext.same_string (nature_libfcgi) or else ext.same_string ("fcgi") then + Result := nature_libfcgi + end + end + end + +feature {NONE} -- nino + + nature_nino: STRING = "nino" + + launch_nino (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + local + launcher: WSF_NINO_SERVICE_LAUNCHER + do + create launcher.make_and_launch (a_service, opts) + end + +feature {NONE} -- cgi + + nature_cgi: STRING = "cgi" + + launch_cgi (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + local + launcher: WSF_CGI_SERVICE_LAUNCHER + do + create launcher.make_and_launch (a_service, opts) + end + +feature {NONE} -- libfcgi + + nature_libfcgi: STRING = "libfcgi" + + launch_libfcgi (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + local + launcher: WSF_LIBFCGI_SERVICE_LAUNCHER + do + create launcher.make_and_launch (a_service, opts) + end + + +end + + diff --git a/examples/roc_api/launcher/default/application_launcher.e b/examples/roc_api/launcher/default/application_launcher.e new file mode 100644 index 0000000..0ef505c --- /dev/null +++ b/examples/roc_api/launcher/default/application_launcher.e @@ -0,0 +1,19 @@ +note + description: "[ + Effective class for APPLICATION_LAUNCHER_I + + You can put modification in this class + ]" + date: "$Date: 2013-06-12 13:55:42 +0200 (mer., 12 juin 2013) $" + revision: "$Revision: 36 $" + +class + APPLICATION_LAUNCHER + +inherit + APPLICATION_LAUNCHER_I + +feature -- Custom + +end + diff --git a/examples/roc_api/launcher/default/application_launcher_i.e b/examples/roc_api/launcher/default/application_launcher_i.e new file mode 100644 index 0000000..2cd4a73 --- /dev/null +++ b/examples/roc_api/launcher/default/application_launcher_i.e @@ -0,0 +1,26 @@ +note + description: "[ + Specific application launcher + + DO NOT EDIT THIS CLASS + + you can customize APPLICATION_LAUNCHER + ]" + date: "$Date: 2013-06-12 13:55:42 +0200 (mer., 12 juin 2013) $" + revision: "$Revision: 36 $" + +deferred class + APPLICATION_LAUNCHER_I + +feature -- Execution + + launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + local + launcher: WSF_SERVICE_LAUNCHER + do + create {WSF_DEFAULT_SERVICE_LAUNCHER} launcher.make_and_launch (a_service, opts) + end + +end + + diff --git a/examples/roc_api/roc.ini b/examples/roc_api/roc.ini new file mode 100644 index 0000000..17eb967 --- /dev/null +++ b/examples/roc_api/roc.ini @@ -0,0 +1,2 @@ +port=8088 +#verbose=true \ No newline at end of file diff --git a/examples/roc_api/roc_api.ecf b/examples/roc_api/roc_api.ecf new file mode 100644 index 0000000..68833eb --- /dev/null +++ b/examples/roc_api/roc_api.ecf @@ -0,0 +1,50 @@ + + + + + /EIFGENs$ + /CVS$ + /.svn$ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/api/site/config/application_configuration.json b/examples/roc_api/site/config/application_configuration.json similarity index 96% rename from api/site/config/application_configuration.json rename to examples/roc_api/site/config/application_configuration.json index 7a93a9a..d493ed8 100644 --- a/api/site/config/application_configuration.json +++ b/examples/roc_api/site/config/application_configuration.json @@ -9,7 +9,7 @@ "connection_string":"Server=localhost;Port=3306;Database=cms_dev;Uid=root;Pwd=;" }, "development": { - "connection_string":"Server=localhost;Port=3306;Database=cms;Uid=root;Pwd=;" + "connection_string":"Server=localhost;Port=3306;Database=cms_dev;Uid=root;Pwd=;" }, "production": { "connection_string":"" diff --git a/examples/roc_api/site/config/cms.ini b/examples/roc_api/site/config/cms.ini new file mode 100644 index 0000000..27ebf1f --- /dev/null +++ b/examples/roc_api/site/config/cms.ini @@ -0,0 +1,6 @@ +engine=smarty +site.name=EWF Web CMS +site.email=your@email.com +var-dir=var +files-dir=files +theme=api diff --git a/examples/roc_api/site/www/static/css/bootstrap.css b/examples/roc_api/site/www/static/css/bootstrap.css new file mode 100644 index 0000000..dede210 --- /dev/null +++ b/examples/roc_api/site/www/static/css/bootstrap.css @@ -0,0 +1,5849 @@ +/*! + * Bootstrap v3.1.0 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +/*! normalize.css v3.0.0 | MIT License | git.io/normalize */ +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + margin: .67em 0; + font-size: 2em; +} +mark { + color: #000; + background: #ff0; +} +small { + font-size: 80%; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -.5em; +} +sub { + bottom: -.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + height: 0; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + margin: 0; + font: inherit; + color: inherit; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + padding: .35em .625em .75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} +legend { + padding: 0; + border: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-spacing: 0; + border-collapse: collapse; +} +td, +th { + padding: 0; +} +@media print { + * { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + select { + background: #fff !important; + } + .navbar { + display: none; + } + .table td, + .table th { + background-color: #fff !important; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 62.5%; + + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.428571429; + color: #333; + background-color: #fff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #428bca; + text-decoration: none; +} +a:hover, +a:focus { + color: #2a6496; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive { + display: block; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + display: inline-block; + max-width: 100%; + height: auto; + padding: 4px; + line-height: 1.428571429; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #999; +} +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 20px; + margin-bottom: 10px; +} +h1 small, +.h1 small, +h2 small, +.h2 small, +h3 small, +.h3 small, +h1 .small, +.h1 .small, +h2 .small, +.h2 .small, +h3 .small, +.h3 .small { + font-size: 65%; +} +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 10px; + margin-bottom: 10px; +} +h4 small, +.h4 small, +h5 small, +.h5 small, +h6 small, +.h6 small, +h4 .small, +.h4 .small, +h5 .small, +.h5 .small, +h6 .small, +.h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 36px; +} +h2, +.h2 { + font-size: 30px; +} +h3, +.h3 { + font-size: 24px; +} +h4, +.h4 { + font-size: 18px; +} +h5, +.h5 { + font-size: 14px; +} +h6, +.h6 { + font-size: 12px; +} +p { + margin: 0 0 10px; +} +.lead { + margin-bottom: 20px; + font-size: 16px; + font-weight: 200; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 21px; + } +} +small, +.small { + font-size: 85%; +} +cite { + font-style: normal; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-justify { + text-align: justify; +} +.text-muted { + color: #999; +} +.text-primary { + color: #428bca; +} +a.text-primary:hover { + color: #3071a9; +} +.text-success { + color: #3c763d; +} +a.text-success:hover { + color: #2b542c; +} +.text-info { + color: #31708f; +} +a.text-info:hover { + color: #245269; +} +.text-warning { + color: #8a6d3b; +} +a.text-warning:hover { + color: #66512c; +} +.text-danger { + color: #a94442; +} +a.text-danger:hover { + color: #843534; +} +.bg-primary { + color: #fff; + background-color: #428bca; +} +a.bg-primary:hover { + background-color: #3071a9; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eee; +} +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + list-style: none; +} +.list-inline > li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} +.list-inline > li:first-child { + padding-left: 0; +} +dl { + margin-top: 0; + margin-bottom: 20px; +} +dt, +dd { + line-height: 1.428571429; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eee; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.428571429; + color: #999; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + text-align: right; + border-right: 5px solid #eee; + border-left: 0; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +blockquote:before, +blockquote:after { + content: ""; +} +address { + margin-bottom: 20px; + font-style: normal; + line-height: 1.428571429; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + white-space: nowrap; + background-color: #f9f2f4; + border-radius: 4px; +} +kbd { + padding: 2px 4px; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 3px; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); +} +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.428571429; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +.row { + margin-right: -15px; + margin-left: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + min-width: 100%; +} +.col-xs-11 { + min-width: 91.66666666666666%; +} +.col-xs-10 { + min-width: 83.33333333333334%; +} +.col-xs-9 { + min-width: 75%; +} +.col-xs-8 { + min-width: 66.66666666666666%; +} +.col-xs-7 { + min-width: 58.333333333333336%; +} +.col-xs-6 { + min-width: 50%; +} +.col-xs-5 { + min-width: 41.66666666666667%; +} +.col-xs-4 { + min-width: 33.33333333333333%; +} +.col-xs-3 { + min-width: 25%; +} +.col-xs-2 { + min-width: 16.666666666666664%; +} +.col-xs-1 { + min-width: 8.333333333333332%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666666666666%; +} +.col-xs-pull-10 { + right: 83.33333333333334%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666666666666%; +} +.col-xs-pull-7 { + right: 58.333333333333336%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666666666667%; +} +.col-xs-pull-4 { + right: 33.33333333333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.666666666666664%; +} +.col-xs-pull-1 { + right: 8.333333333333332%; +} +.col-xs-pull-0 { + right: 0; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666666666666%; +} +.col-xs-push-10 { + left: 83.33333333333334%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666666666666%; +} +.col-xs-push-7 { + left: 58.333333333333336%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666666666667%; +} +.col-xs-push-4 { + left: 33.33333333333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.666666666666664%; +} +.col-xs-push-1 { + left: 8.333333333333332%; +} +.col-xs-push-0 { + left: 0; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666666666666%; +} +.col-xs-offset-10 { + margin-left: 83.33333333333334%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666666666666%; +} +.col-xs-offset-7 { + margin-left: 58.333333333333336%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666666666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.666666666666664%; +} +.col-xs-offset-1 { + margin-left: 8.333333333333332%; +} +.col-xs-offset-0 { + margin-left: 0; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + min-width: 100%; + } + .col-sm-11 { + min-width: 91.66666666666666%; + } + .col-sm-10 { + min-width: 83.33333333333334%; + } + .col-sm-9 { + min-width: 75%; + } + .col-sm-8 { + min-width: 66.66666666666666%; + } + .col-sm-7 { + min-width: 58.333333333333336%; + } + .col-sm-6 { + min-width: 50%; + } + .col-sm-5 { + min-width: 41.66666666666667%; + } + .col-sm-4 { + min-width: 33.33333333333333%; + } + .col-sm-3 { + min-width: 25%; + } + .col-sm-2 { + min-width: 16.666666666666664%; + } + .col-sm-1 { + min-width: 8.333333333333332%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666666666666%; + } + .col-sm-pull-10 { + right: 83.33333333333334%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666666666666%; + } + .col-sm-pull-7 { + right: 58.333333333333336%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666666666667%; + } + .col-sm-pull-4 { + right: 33.33333333333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.666666666666664%; + } + .col-sm-pull-1 { + right: 8.333333333333332%; + } + .col-sm-pull-0 { + right: 0; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666666666666%; + } + .col-sm-push-10 { + left: 83.33333333333334%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666666666666%; + } + .col-sm-push-7 { + left: 58.333333333333336%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666666666667%; + } + .col-sm-push-4 { + left: 33.33333333333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.666666666666664%; + } + .col-sm-push-1 { + left: 8.333333333333332%; + } + .col-sm-push-0 { + left: 0; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666666666666%; + } + .col-sm-offset-10 { + margin-left: 83.33333333333334%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666666666666%; + } + .col-sm-offset-7 { + margin-left: 58.333333333333336%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666666666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.666666666666664%; + } + .col-sm-offset-1 { + margin-left: 8.333333333333332%; + } + .col-sm-offset-0 { + margin-left: 0; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + min-width: 100%; + } + .col-md-11 { + min-width: 91.66666666666666%; + } + .col-md-10 { + min-width: 83.33333333333334%; + } + .col-md-9 { + min-width: 75%; + } + .col-md-8 { + min-width: 66.66666666666666%; + } + .col-md-7 { + min-width: 58.333333333333336%; + } + .col-md-6 { + min-width: 50%; + } + .col-md-5 { + min-width: 41.66666666666667%; + } + .col-md-4 { + min-width: 33.33333333333333%; + } + .col-md-3 { + min-width: 25%; + } + .col-md-2 { + min-width: 16.666666666666664%; + } + .col-md-1 { + min-width: 8.333333333333332%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666666666666%; + } + .col-md-pull-10 { + right: 83.33333333333334%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666666666666%; + } + .col-md-pull-7 { + right: 58.333333333333336%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666666666667%; + } + .col-md-pull-4 { + right: 33.33333333333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.666666666666664%; + } + .col-md-pull-1 { + right: 8.333333333333332%; + } + .col-md-pull-0 { + right: 0; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666666666666%; + } + .col-md-push-10 { + left: 83.33333333333334%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666666666666%; + } + .col-md-push-7 { + left: 58.333333333333336%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666666666667%; + } + .col-md-push-4 { + left: 33.33333333333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.666666666666664%; + } + .col-md-push-1 { + left: 8.333333333333332%; + } + .col-md-push-0 { + left: 0; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666666666666%; + } + .col-md-offset-10 { + margin-left: 83.33333333333334%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666666666666%; + } + .col-md-offset-7 { + margin-left: 58.333333333333336%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666666666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.666666666666664%; + } + .col-md-offset-1 { + margin-left: 8.333333333333332%; + } + .col-md-offset-0 { + margin-left: 0; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + min-width: 100%; + } + .col-lg-11 { + min-width: 91.66666666666666%; + } + .col-lg-10 { + min-width: 83.33333333333334%; + } + .col-lg-9 { + min-width: 75%; + } + .col-lg-8 { + min-width: 66.66666666666666%; + } + .col-lg-7 { + min-width: 58.333333333333336%; + } + .col-lg-6 { + min-width: 50%; + } + .col-lg-5 { + min-width: 41.66666666666667%; + } + .col-lg-4 { + min-width: 33.33333333333333%; + } + .col-lg-3 { + min-width: 25%; + } + .col-lg-2 { + min-width: 16.666666666666664%; + } + .col-lg-1 { + min-width: 8.333333333333332%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666666666666%; + } + .col-lg-pull-10 { + right: 83.33333333333334%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666666666666%; + } + .col-lg-pull-7 { + right: 58.333333333333336%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666666666667%; + } + .col-lg-pull-4 { + right: 33.33333333333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.666666666666664%; + } + .col-lg-pull-1 { + right: 8.333333333333332%; + } + .col-lg-pull-0 { + right: 0; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666666666666%; + } + .col-lg-push-10 { + left: 83.33333333333334%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666666666666%; + } + .col-lg-push-7 { + left: 58.333333333333336%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666666666667%; + } + .col-lg-push-4 { + left: 33.33333333333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.666666666666664%; + } + .col-lg-push-1 { + left: 8.333333333333332%; + } + .col-lg-push-0 { + left: 0; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666666666666%; + } + .col-lg-offset-10 { + margin-left: 83.33333333333334%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666666666666%; + } + .col-lg-offset-7 { + margin-left: 58.333333333333336%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666666666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.666666666666664%; + } + .col-lg-offset-1 { + margin-left: 8.333333333333332%; + } + .col-lg-offset-0 { + margin-left: 0; + } +} +table { + max-width: 100%; + background-color: transparent; +} +th { + text-align: left; +} +.table { + width: 100%; + margin-bottom: 20px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.428571429; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-child(odd) > td, +.table-striped > tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover > td, +.table-hover > tbody > tr:hover > th { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + display: table-column; + float: none; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + display: table-cell; + float: none; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +@media (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-x: scroll; + overflow-y: hidden; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + /* IE8-9 */ + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.428571429; + color: #555; +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.428571429; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); +} +.form-control:-moz-placeholder { + color: #999; +} +.form-control::-moz-placeholder { + color: #999; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #999; +} +.form-control::-webkit-input-placeholder { + color: #999; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + cursor: not-allowed; + background-color: #eee; + opacity: 1; +} +textarea.form-control { + height: auto; +} +input[type="date"] { + line-height: 34px; +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + display: block; + min-height: 20px; + padding-left: 20px; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + display: inline; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + float: left; + margin-left: -20px; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +.radio[disabled], +.radio-inline[disabled], +.checkbox[disabled], +.checkbox-inline[disabled], +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"], +fieldset[disabled] .radio, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.input-lg { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} +select.input-lg { + height: 46px; + line-height: 46px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 42.5px; +} +.has-feedback .form-control-feedback { + position: absolute; + top: 25px; + right: 0; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + background-color: #dff0d8; + border-color: #3c763d; +} +.has-success .form-control-feedback { + color: #3c763d; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #8a6d3b; +} +.has-warning .form-control-feedback { + color: #8a6d3b; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline { + color: #a94442; +} +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; +} +.has-error .input-group-addon { + color: #a94442; + background-color: #f2dede; + border-color: #a94442; +} +.has-error .form-control-feedback { + color: #a94442; +} +.form-control-static { + margin-bottom: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .control-label, +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} +.form-horizontal .form-control-static { + padding-top: 7px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + } +} +.form-horizontal .has-feedback .form-control-feedback { + top: 0; + right: 15px; +} +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.428571429; + text-align: center; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.btn:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus { + color: #333; + text-decoration: none; +} +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + pointer-events: none; + cursor: not-allowed; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; + opacity: .65; +} +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} +.btn-default:hover, +.btn-default:focus, +.btn-default:active, +.btn-default.active, +.open .dropdown-toggle.btn-default { + color: #333; + background-color: #ebebeb; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #fff; + border-color: #ccc; +} +.btn-default .badge { + color: #fff; + background-color: #333; +} +.btn-primary { + color: #fff; + background-color: #428bca; + border-color: #357ebd; +} +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.open .dropdown-toggle.btn-primary { + color: #fff; + background-color: #3276b1; + border-color: #285e8e; +} +.btn-primary:active, +.btn-primary.active, +.open .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #428bca; + border-color: #357ebd; +} +.btn-primary .badge { + color: #428bca; + background-color: #fff; +} +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.open .dropdown-toggle.btn-success { + color: #fff; + background-color: #47a447; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.open .dropdown-toggle.btn-info { + color: #fff; + background-color: #39b3d7; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.open .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ed9c28; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.open .dropdown-toggle.btn-danger { + color: #fff; + background-color: #d2322d; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-link { + font-weight: normal; + color: #428bca; + cursor: pointer; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #2a6496; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #999; + text-decoration: none; +} +.btn-lg { + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} +.btn-sm { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height .35s ease; + transition: height .35s ease; +} +@font-face { + font-family: 'Glyphicons Halflings'; + + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\2a"; +} +.glyphicon-plus:before { + content: "\2b"; +} +.glyphicon-euro:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 14px; + list-style: none; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.428571429; + color: #333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #fff; + text-decoration: none; + background-color: #428bca; + outline: 0; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + right: 0; + left: auto; +} +.dropdown-menu-left { + right: auto; + left: 0; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.428571429; + color: #999; +} +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + content: ""; + border-top: 0; + border-bottom: 4px solid; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; + } + .navbar-right .dropdown-menu-left { + right: auto; + left: 0; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus { + outline: none; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child > .btn:last-child, +.btn-group > .btn-group:first-child > .dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn-group:last-child > .btn:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: 4px; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + display: table-cell; + float: none; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +[data-toggle="buttons"] > .btn > input[type="radio"], +[data-toggle="buttons"] > .btn > input[type="checkbox"] { + display: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-right: 0; + padding-left: 0; +} +.input-group .form-control { + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 46px; + line-height: 46px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #555; + text-align: center; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + margin-left: -1px; +} +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eee; +} +.nav > li.disabled > a { + color: #999; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #999; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eee; + border-color: #428bca; +} +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.428571429; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eee #eee #ddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555; + cursor: default; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 4px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #fff; + background-color: #428bca; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + max-height: 340px; + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + -webkit-overflow-scrolling: touch; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-right: 0; + padding-left: 0; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + height: 20px; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} +.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-toggle:focus { + outline: none; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 7.5px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } + .navbar-nav.navbar-right:last-child { + margin-right: -15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + } +} +.navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-form.navbar-right:last-child { + margin-right: -15px; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} +.navbar-btn.btn-sm { + margin-top: 10px; + margin-bottom: 10px; +} +.navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; +} +.navbar-text { + margin-top: 15px; + margin-bottom: 15px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-right: 15px; + margin-left: 15px; + } + .navbar-text.navbar-right:last-child { + margin-right: 0; + } +} +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} +.navbar-default .navbar-brand { + color: #777; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #777; +} +.navbar-default .navbar-nav > li > a { + color: #777; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555; + background-color: #e7e7e7; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #ddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #ddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #888; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #555; + background-color: #e7e7e7; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #ccc; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #777; +} +.navbar-default .navbar-link:hover { + color: #333; +} +.navbar-inverse { + background-color: #222; + border-color: #080808; +} +.navbar-inverse .navbar-brand { + color: #999; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #999; +} +.navbar-inverse .navbar-nav > li > a { + color: #999; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #080808; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #333; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #101010; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + color: #fff; + background-color: #080808; +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #999; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #999; +} +.navbar-inverse .navbar-link:hover { + color: #fff; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + padding: 0 5px; + color: #ccc; + content: "/\00a0"; +} +.breadcrumb > .active { + color: #999; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.428571429; + color: #428bca; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + color: #2a6496; + background-color: #eee; + border-color: #ddd; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 2; + color: #fff; + cursor: default; + background-color: #428bca; + border-color: #428bca; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #999; + cursor: not-allowed; + background-color: #fff; + border-color: #ddd; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eee; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999; + cursor: not-allowed; + background-color: #fff; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +.label[href]:hover, +.label[href]:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #999; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #808080; +} +.label-primary { + background-color: #428bca; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #3071a9; +} +.label-success { + background-color: #5cb85c; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + background-color: #999; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +a.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #428bca; + background-color: #fff; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding: 30px; + margin-bottom: 30px; + color: inherit; + background-color: #eee; +} +.jumbotron h1, +.jumbotron .h1 { + color: inherit; +} +.jumbotron p { + margin-bottom: 15px; + font-size: 21px; + font-weight: 200; +} +.container .jumbotron { + border-radius: 6px; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron { + padding-right: 60px; + padding-left: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 63px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 20px; + line-height: 1.428571429; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + display: block; + max-width: 100%; + height: auto; + margin-right: auto; + margin-left: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #428bca; +} +.thumbnail .caption { + padding: 9px; + color: #333; +} +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable { + padding-right: 35px; +} +.alert-dismissable .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #843534; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); +} +.progress-bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #fff; + text-align: center; + background-color: #428bca; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + -webkit-transition: width .6s ease; + transition: width .6s ease; +} +.progress-striped .progress-bar { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-size: 40px 40px; +} +.progress.active .progress-bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #5cb85c; +} +.progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.media, +.media-body { + overflow: hidden; + zoom: 1; +} +.media, +.media .media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media-object { + display: block; +} +.media-heading { + margin: 0 0 5px; +} +.media > .pull-left { + margin-right: 10px; +} +.media > .pull-right { + margin-left: 10px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + padding-left: 0; + margin-bottom: 20px; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; +} +.list-group-item:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +a.list-group-item { + color: #555; +} +a.list-group-item .list-group-item-heading { + color: #333; +} +a.list-group-item:hover, +a.list-group-item:focus { + text-decoration: none; + background-color: #f5f5f5; +} +a.list-group-item.active, +a.list-group-item.active:hover, +a.list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #428bca; + border-color: #428bca; +} +a.list-group-item.active .list-group-item-heading, +a.list-group-item.active:hover .list-group-item-heading, +a.list-group-item.active:focus .list-group-item-heading { + color: inherit; +} +a.list-group-item.active .list-group-item-text, +a.list-group-item.active:hover .list-group-item-text, +a.list-group-item.active:focus .list-group-item-text { + color: #e1edf7; +} +.list-group-item-success { + color: #3c763d; + background-color: #dff0d8; +} +a.list-group-item-success { + color: #3c763d; +} +a.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +a.list-group-item-success:focus { + color: #3c763d; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +a.list-group-item-success.active:hover, +a.list-group-item-success.active:focus { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; +} +.list-group-item-info { + color: #31708f; + background-color: #d9edf7; +} +a.list-group-item-info { + color: #31708f; +} +a.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +a.list-group-item-info:focus { + color: #31708f; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +a.list-group-item-info.active:hover, +a.list-group-item-info.active:focus { + color: #fff; + background-color: #31708f; + border-color: #31708f; +} +.list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; +} +a.list-group-item-warning { + color: #8a6d3b; +} +a.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +a.list-group-item-warning:focus { + color: #8a6d3b; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; +} +.list-group-item-danger { + color: #a94442; + background-color: #f2dede; +} +a.list-group-item-danger { + color: #a94442; +} +a.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +a.list-group-item-danger:focus { + color: #a94442; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus { + color: #fff; + background-color: #a94442; + border-color: #a94442; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: 0 1px 1px rgba(0, 0, 0, .05); +} +.panel-body { + padding: 15px; +} +.panel > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group .list-group-item:first-child { + border-top: 0; +} +.panel > .list-group .list-group-item:last-child { + border-bottom: 0; +} +.panel > .list-group:first-child .list-group-item:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .list-group:last-child .list-group-item:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table { + margin-bottom: 0; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive { + border-top: 1px solid #ddd; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th, +.panel > .table-bordered > tfoot > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:first-child > th, +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > tfoot > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:first-child > td { + border-top: 0; +} +.panel > .table-bordered > thead > tr:last-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:last-child > th, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-bordered > thead > tr:last-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; +} +.panel > .table-responsive { + margin-bottom: 0; + border: 0; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} +.panel-title > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel-group { + margin-bottom: 20px; +} +.panel-group .panel { + margin-bottom: 0; + overflow: hidden; + border-radius: 4px; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse .panel-body { + border-top: 1px solid #ddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #ddd; +} +.panel-default { + border-color: #ddd; +} +.panel-default > .panel-heading { + color: #333; + background-color: #f5f5f5; + border-color: #ddd; +} +.panel-default > .panel-heading + .panel-collapse .panel-body { + border-top-color: #ddd; +} +.panel-default > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #ddd; +} +.panel-primary { + border-color: #428bca; +} +.panel-primary > .panel-heading { + color: #fff; + background-color: #428bca; + border-color: #428bca; +} +.panel-primary > .panel-heading + .panel-collapse .panel-body { + border-top-color: #428bca; +} +.panel-primary > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #428bca; +} +.panel-success { + border-color: #d6e9c6; +} +.panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.panel-success > .panel-heading + .panel-collapse .panel-body { + border-top-color: #d6e9c6; +} +.panel-success > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #d6e9c6; +} +.panel-info { + border-color: #bce8f1; +} +.panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.panel-info > .panel-heading + .panel-collapse .panel-body { + border-top-color: #bce8f1; +} +.panel-info > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #bce8f1; +} +.panel-warning { + border-color: #faebcc; +} +.panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.panel-warning > .panel-heading + .panel-collapse .panel-body { + border-top-color: #faebcc; +} +.panel-warning > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #faebcc; +} +.panel-danger { + border-color: #ebccd1; +} +.panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.panel-danger > .panel-heading + .panel-collapse .panel-body { + border-top-color: #ebccd1; +} +.panel-danger > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #ebccd1; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, .15); +} +.well-lg { + padding: 24px; + border-radius: 6px; +} +.well-sm { + padding: 9px; + border-radius: 3px; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: .2; +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + filter: alpha(opacity=50); + opacity: .5; +} +button.close { + -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; +} +.modal-open { + overflow: hidden; +} +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: auto; + overflow-y: scroll; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transition: -webkit-transform .3s ease-out; + -moz-transition: -moz-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + transform: translate(0, -25%); +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + outline: none; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); + box-shadow: 0 3px 9px rgba(0, 0, 0, .5); +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} +.modal-backdrop.fade { + filter: alpha(opacity=0); + opacity: 0; +} +.modal-backdrop.in { + filter: alpha(opacity=50); + opacity: .5; +} +.modal-header { + min-height: 16.428571429px; + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.428571429; +} +.modal-body { + position: relative; + padding: 20px; +} +.modal-footer { + padding: 19px 20px 20px; + margin-top: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + } + .modal-sm { + width: 300px; + } + .modal-lg { + width: 900px; + } +} +.tooltip { + position: absolute; + z-index: 1030; + display: block; + font-size: 12px; + line-height: 1.4; + visibility: visible; + filter: alpha(opacity=0); + opacity: 0; +} +.tooltip.in { + filter: alpha(opacity=90); + opacity: .9; +} +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #000; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-left .tooltip-arrow { + bottom: 0; + left: 5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-right .tooltip-arrow { + right: 5px; + bottom: 0; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + left: 5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + right: 5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + white-space: normal; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + box-shadow: 0 5px 10px rgba(0, 0, 0, .2); +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover .arrow { + border-width: 11px; +} +.popover .arrow:after { + content: ""; + border-width: 10px; +} +.popover.top .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, .25); + border-bottom-width: 0; +} +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + content: " "; + border-top-color: #fff; + border-bottom-width: 0; +} +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, .25); + border-left-width: 0; +} +.popover.right .arrow:after { + bottom: -10px; + left: 1px; + content: " "; + border-right-color: #fff; + border-left-width: 0; +} +.popover.bottom .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, .25); +} +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + content: " "; + border-top-width: 0; + border-bottom-color: #fff; +} +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, .25); +} +.popover.left .arrow:after { + right: 1px; + bottom: -10px; + content: " "; + border-right-width: 0; + border-left-color: #fff; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; + line-height: 1; +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); + filter: alpha(opacity=50); + opacity: .5; +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, .5) 0%), color-stop(rgba(0, 0, 0, .0001) 100%)); + background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, .0001) 0%), color-stop(rgba(0, 0, 0, .5) 100%)); + background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control:hover, +.carousel-control:focus { + color: #fff; + text-decoration: none; + filter: alpha(opacity=90); + outline: none; + opacity: .9; +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + margin-left: -10px; + font-family: serif; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); + border: 1px solid #fff; + border-radius: 10px; +} +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #fff; +} +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicons-chevron-left, + .carousel-control .glyphicons-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + margin-left: -15px; + font-size: 30px; + } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} +.clearfix:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; + visibility: hidden !important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +tr.visible-xs, +th.visible-xs, +td.visible-xs { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +.visible-sm, +tr.visible-sm, +th.visible-sm, +td.visible-sm { + display: none !important; +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +.visible-md, +tr.visible-md, +th.visible-md, +td.visible-md { + display: none !important; +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +.visible-lg, +tr.visible-lg, +th.visible-lg, +td.visible-lg { + display: none !important; +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .hidden-xs, + tr.hidden-xs, + th.hidden-xs, + td.hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm, + tr.hidden-sm, + th.hidden-sm, + td.hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md, + tr.hidden-md, + th.hidden-md, + td.hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg, + tr.hidden-lg, + th.hidden-lg, + td.hidden-lg { + display: none !important; + } +} +.visible-print, +tr.visible-print, +th.visible-print, +td.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +@media print { + .hidden-print, + tr.hidden-print, + th.hidden-print, + td.hidden-print { + display: none !important; + } +} + +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.glyphicon-home:before { + content: "\e021"; +} + +/*# sourceMappingURL=bootstrap.css.map */ diff --git a/examples/roc_api/site/www/static/css/dashboard.css b/examples/roc_api/site/www/static/css/dashboard.css new file mode 100644 index 0000000..a126fc3 --- /dev/null +++ b/examples/roc_api/site/www/static/css/dashboard.css @@ -0,0 +1,357 @@ +/* + * Base structure + */ + +/* Move down content because we have a fixed navbar that is 36px tall on small screen */ +body { + padding-top: 40px; +} +/* On large screen, we give it more space and the navbar is 30px tall. */ +@media (min-width: 768px) { + body { + padding-top: 45px; + } +} + + +/* + * Global add-ons + */ + +h1 { + margin-top: initial; + margin-bottom: 5px; +} + +h2.sub-header{ + margin-top: 1px; + margin-bottom: 1px; + border-bottom: 1px solid #eee; +} + + +.container .jumbotron { + padding: 10px; + text-align: center; +} + + +/* + * Sidebar + */ + +/* Hide for mobile, show later */ +.sidebar { + display: none; +} +@media (min-width: 768px) { + .sidebar { + position: fixed; + top: 0; + left: 0; + bottom: 0; + z-index: 1000; + display: block; + padding: 70px 20px 20px; + background-color: #f5f5f5; + border-right: 1px solid #eee; + } +} + +/* Sidebar navigation */ +.nav-sidebar { + margin-left: -20px; + margin-right: -21px; /* 20px padding + 1px border */ + margin-bottom: 20px; +} +.nav-sidebar > li > a { + padding-left: 20px; + padding-right: 20px; +} +.nav-sidebar > .active > a { + color: #fff; + background-color: #428bca; +} + + +/* + * Main content + */ + +.main { + padding: 3px; +} +@media (min-width: 768px) { + .main { + padding-left: 15px; + padding-right: 15px; + } +} +.main .page-header { + margin-top: 0; +} + + +/* + * Placeholder dashboard ideas + */ + +.placeholders { + margin-bottom: 30px; + text-align: center; +} +.placeholders h4 { + margin-bottom: 0; +} +.placeholder { + margin-bottom: 20px; +} +.placeholder img { + border-radius: 50%; +} + +.navbar-default { + background-color:#194573; + border-color: #400040; +} +.navbar-default .navbar-brand { + color: #ffffff; +} +.navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus { + color: #ffffff; +} +.navbar-default .navbar-text { + color: #ffffff; +} +.navbar-default .navbar-nav > li > a { + color: #ffffff; +} +.navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus { + color: #ffffff; +} +.navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus { + color: #ffffff; + background-color: #400040; +} +.navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus { + color: #ffffff; + background-color: #400040; +} +.navbar-default .navbar-toggle { + border-color: #400040; +} +.navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus { + background-color: #400040; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #ffffff; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #ffffff; +} +.navbar-default .navbar-link { + color: #ffffff; +} +.navbar-default .navbar-link:hover { + color: #ffffff; +} + +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #ffffff; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #ffffff; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #ffffff; + background-color: #400040; + } +} + +.navbar-nav > li > a {padding-top:5px !important; padding-bottom:5px !important;} +.navbar {min-height:30px !important} + +.navbar-brand { + float: left; + padding: 15px; + padding-top: 5px; + padding-right: 15px; + padding-bottom: 5px; + padding-left: 15px; + font-size: 18px; + line-height: 18px; + height: 30px; +} + + +/* Tooltips */ +.blue-tooltip + .tooltip > .tooltip-inner {background-color: #FF;} +.blue-tooltip + .tooltip > .tooltip-arrow { border-bottom-color:#FF; } + + +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-top-color: #000000; + border-width: 5px 5px 0; +} +.tooltip-inner { + text-align: left; + color: #000; + background: #fff; + border: solid 1px #000000; + max-width: 450px +} + +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +/* pre */ +pre { + word-wrap: code; + white-space: pre-wrap; + background-color:white; +} + + +/* Container -Fluid */ +.container-fluid { + padding: 0 2px; +} +@media (min-width: 768px) { + .container-fluid { + padding: 0 5px; + } +} + +.container-fluid .row { + margin: 0px; +} + +.row-padding { + margin-top: 25px; + margin-bottom: 25px; +} + +/* Width for the text field to enter a bug report number in the reports page. + * We put a maximum width to override the width value coming from `form-control'. */ +.form-bug-number-entry { + max-width: 100px; +} + +/* Default width for the entries in a table like layout. */ +.form-inline .form-control { + width: 95%; +} + +.form-inline .checkbox { + font-weight: initial; + vertical-align: top; +} + +/* Note that there is also a class called label. */ +label { + padding-right: 5px; +} + +.label { + padding: 0px; + padding-right: 5px; +} + +.label-primary-api-default { + display: inline-block; + width: 105px; + text-align: left; + background: #fff; + color: #000; + font-size: 100%; + text-align: right; +} + + +.label-primary-api-interactions { + display: inline-block; + padding-right: 5px; + text-align: left; + color: #000; + font-size: 100%; +} + + +pre { + padding: 1.5px; + display: block; + margin: 0 0 10px; + font-size: 12px; + font-family: monospace; + line-height: 1.428571429; + word-break: break-word; + word-wrap: break-word; + color: #333; + border: 0px; + border-radius: 4px; +} + + +/* No padding, so that nested columns are always properly aligned. */ +.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12 { + padding-left: 0px; + padding-right: 0px; +} + +.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td { + padding:2px; + vertical-align: middle; +} + +.form-control{ + height:inherit; + padding: 1px 2px; + margin: 1px; +} + +.btn { + padding: 1px 12px; + margin: 1px; + min-width: 100px; +} + +.dropdown-toggle, .login { + cursor: pointer; +} + +.pager { + margin:10px 0; +} + +.pager li>a,.pager li>span { + padding:1px 12px; + border-radius:8px; +} + +.well { + padding: 9px; + margin-bottom: 10px; + min-height: 44px; +} + +.panel-heading { + background-color: #ddeaf2 !important; +} + +.private-panel-border { + border: solid 1px #DBA458 !important; +} + +.private-panel { + background-color: #f2eadd !important; +} diff --git a/examples/roc_api/site/www/static/images/ajax-loader.gif b/examples/roc_api/site/www/static/images/ajax-loader.gif new file mode 100644 index 0000000..cd1a998 Binary files /dev/null and b/examples/roc_api/site/www/static/images/ajax-loader.gif differ diff --git a/examples/roc_api/site/www/static/images/favicon.ico b/examples/roc_api/site/www/static/images/favicon.ico new file mode 100644 index 0000000..676d744 Binary files /dev/null and b/examples/roc_api/site/www/static/images/favicon.ico differ diff --git a/examples/roc_api/site/www/static/js/roc.js b/examples/roc_api/site/www/static/js/roc.js new file mode 100644 index 0000000..c7accef --- /dev/null +++ b/examples/roc_api/site/www/static/js/roc.js @@ -0,0 +1,108 @@ +/* + * EWF CMS javascript based on JQuery + */ + +/** + * Override jQuery.fn.init to guard against XSS attacks. + * + * See http://bugs.jquery.com/ticket/9521 + */ + +(function () { + var jquery_init = jQuery.fn.init; + jQuery.fn.init = function (selector, context, rootjQuery) { + // If the string contains a "#" before a "<", treat it as invalid HTML. + if (selector && typeof selector === 'string') { + var hash_position = selector.indexOf('#'); + if (hash_position >= 0) { + var bracket_position = selector.indexOf('<'); + if (bracket_position > hash_position) { + throw 'Syntax error, unrecognized expression: ' + selector; + } + } + } + return jquery_init.call(this, selector, context, rootjQuery); + }; + jQuery.fn.init.prototype = jquery_init.prototype; +})(); + + +var ROC = ROC || { }; + +$('body').on('click',"a[rel='node']",function(e){ + + e.preventDefault(); + /* + if uncomment the above line, html5 nonsupported browers won't change the url but will display the ajax content; + if commented, html5 nonsupported browers will reload the page to the specified link. + */ + + //get the link location that was clicked + pageurl = $(this).attr('href'); + + spinner = "

Loading content..

loading...
"; + //to get the ajax content and display in div with class 'main' + $.ajax({url:pageurl+'?rel=node',success: function(data){ + $('.main').html(data); + }}); + + //to change the browser URL to the given link location + //if(pageurl!=window.location){ + //window.history.pushState({path:pageurl},'',pageurl); + //} + //stop refreshing to the page given in + return false; +}); + +$('body').on('click',"a[rel='register']",function(e){ + + e.preventDefault(); + /* + if uncomment the above line, html5 nonsupported browers won't change the url but will display the ajax content; + if commented, html5 nonsupported browers will reload the page to the specified link. + */ + + //get the link location that was clicked + pageurl = $(this).attr('href'); + + spinner = "

Loading content..

loading...
"; + //to get the ajax content and display in div with class 'main' + $.ajax({url:pageurl+'?rel=node',success: function(data){ + $('.main').html(data); + }}); + + //to change the browser URL to the given link location + //if(pageurl!=window.location){ + //window.history.pushState({path:pageurl},'',pageurl); + //} + //stop refreshing to the page given in + return false; +}); + + + +$("a[rel='node']").click(function(e){ + e.preventDefault(); + /* + if uncomment the above line, html5 nonsupported browers won't change the url but will display the ajax content; + if commented, html5 nonsupported browers will reload the page to the specified link. + */ + + //get the link location that was clicked + pageurl = $(this).attr('href'); + + spinner = "

Loading content..

loading...
"; + //to get the ajax content and display in div with class 'main' + $.ajax({url:pageurl+'?rel=node',success: function(data){ + $('.main').html(data); + }}); + + //to change the browser URL to the given link location + //if(pageurl!=window.location){ + //window.history.pushState({path:pageurl},'',pageurl); + //} + //stop refreshing to the page given in + return false; +}); + + diff --git a/examples/roc_api/site/www/template/html/layout2.tpl b/examples/roc_api/site/www/template/html/layout2.tpl new file mode 100644 index 0000000..34a5659 --- /dev/null +++ b/examples/roc_api/site/www/template/html/layout2.tpl @@ -0,0 +1,40 @@ + + + + {include file="master2/head.tpl"/} + + + + + {include file="master2/site_navigation.tpl"/} + + + +
+
+
+
+ {include file="master2/content.tpl"/} +
+
+
+ + + + {if condition="$web"} + {include file="master2/optional_enhancement_js.tpl"/} + {/if} + + {if condition="$html"} + {include file="master2/optional_enhancement_js.tpl"/} + {/if} + + + + \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/master2/content.tpl b/examples/roc_api/site/www/template/html/master2/content.tpl new file mode 100644 index 0000000..b18c5dd --- /dev/null +++ b/examples/roc_api/site/www/template/html/master2/content.tpl @@ -0,0 +1,11 @@ + +
+

Top most recent nodes


+ + + {foreach from="$nodes" item="item"} + + {/foreach} +
diff --git a/examples/roc_api/site/www/template/html/master2/error.tpl b/examples/roc_api/site/www/template/html/master2/error.tpl new file mode 100644 index 0000000..0ca7ad0 --- /dev/null +++ b/examples/roc_api/site/www/template/html/master2/error.tpl @@ -0,0 +1,18 @@ +

Error: {$code/}

+ +{assign name="status400" value="400"/} +{assign name="status404" value="404"/} +{assign name="status500" value="500"/} + +{if condition="$code ~ $status500"} +

Internal server error, for the request {$request/}

+{/if} + + +{if condition="$code ~ $status404"} +

Resourse not found, for the request {$request/}

+{/if} + +{if condition="$code ~ $status400"} +

Bad request, the request {$request/} is not valid

+{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/master2/footer.tpl b/examples/roc_api/site/www/template/html/master2/footer.tpl new file mode 100644 index 0000000..11fe183 --- /dev/null +++ b/examples/roc_api/site/www/template/html/master2/footer.tpl @@ -0,0 +1,7 @@ + +
+

API Documentation     + Questions? Comments? Let us know!

+

© Copyright 2014 Eiffel Software -- Privacy Policy +

+
\ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/master2/head.tpl b/examples/roc_api/site/www/template/html/master2/head.tpl new file mode 100644 index 0000000..4ba4616 --- /dev/null +++ b/examples/roc_api/site/www/template/html/master2/head.tpl @@ -0,0 +1,10 @@ + + +Eiffel RESTonCMS +{if condition="$web"} + {include file="master2/optional_styling_css.tpl"/} +{/if} +{if condition="$html"} + {include file="master2/optional_styling_css.tpl"/} +{/if} + diff --git a/examples/roc_api/site/www/template/html/master2/header.tpl b/examples/roc_api/site/www/template/html/master2/header.tpl new file mode 100644 index 0000000..ce8ec71 --- /dev/null +++ b/examples/roc_api/site/www/template/html/master2/header.tpl @@ -0,0 +1,2 @@ +

RESTonCMS

+

Tagline

\ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/master2/logoff.tpl b/examples/roc_api/site/www/template/html/master2/logoff.tpl new file mode 100644 index 0000000..8139dc7 --- /dev/null +++ b/examples/roc_api/site/www/template/html/master2/logoff.tpl @@ -0,0 +1,5 @@ +

You have successfully signed out

+ +You may want to return + +Press this neat little button:Take Me Home diff --git a/examples/roc_api/site/www/template/html/master2/main_navigation.tpl b/examples/roc_api/site/www/template/html/master2/main_navigation.tpl new file mode 100644 index 0000000..88365d7 --- /dev/null +++ b/examples/roc_api/site/www/template/html/master2/main_navigation.tpl @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/master2/optional_enhancement_js.tpl b/examples/roc_api/site/www/template/html/master2/optional_enhancement_js.tpl new file mode 100644 index 0000000..1353b83 --- /dev/null +++ b/examples/roc_api/site/www/template/html/master2/optional_enhancement_js.tpl @@ -0,0 +1,5 @@ + + +{if condition="$web"} + +{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/master2/optional_styling_css.tpl b/examples/roc_api/site/www/template/html/master2/optional_styling_css.tpl new file mode 100644 index 0000000..f56d770 --- /dev/null +++ b/examples/roc_api/site/www/template/html/master2/optional_styling_css.tpl @@ -0,0 +1,9 @@ +{if condition="$html"} + + + +{/if} +{if condition="$web"} + + +{/if} diff --git a/examples/roc_api/site/www/template/html/master2/site_navigation.tpl b/examples/roc_api/site/www/template/html/master2/site_navigation.tpl new file mode 100644 index 0000000..a75760c --- /dev/null +++ b/examples/roc_api/site/www/template/html/master2/site_navigation.tpl @@ -0,0 +1,27 @@ + + + + \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/modules/navigation.tpl b/examples/roc_api/site/www/template/html/modules/navigation.tpl new file mode 100644 index 0000000..ee2d15e --- /dev/null +++ b/examples/roc_api/site/www/template/html/modules/navigation.tpl @@ -0,0 +1,8 @@ +{if isset="$user"} + Logoff +{/if} +{unless isset="$user"} + Login + Register +{/unless} +List of Nodes diff --git a/examples/roc_api/site/www/template/html/modules/node.tpl b/examples/roc_api/site/www/template/html/modules/node.tpl new file mode 100644 index 0000000..0f6173f --- /dev/null +++ b/examples/roc_api/site/www/template/html/modules/node.tpl @@ -0,0 +1,174 @@ +{if condition="html"} + + + + {include file="master2/head.tpl"/} + + +{/if} + +{unless condition="$web"} + + {include file="master2/site_navigation.tpl"/} +{/unless} + + +{if condition="html"} + +
+
+
+
+{/if} + + +
+ {if condition="$web"} + + {/if} + {if condition="$html"} + + {/if} +
+
+ {if isset="$node"} +
+
+
+
+

{$node.title/}

+
+
+
{$node.content/}
+
+
+
+ {/if} +
+ +
+ {if isset="$user"} +
+
+
+ {if isset="$node"} + +
+ {/if} +
+
+
+ {if isset="$user"} +
+
+ + {if isset="$node"} +
+ +
+ Delete Node + +
+ +
+
+
+ {/if} +
+ {/if} +
+
+
+ +{if condition="html"} +
+
+
+{/if} + + +{if condition="html"} + + + + {include file="master2/optional_enhancement_js.tpl"/} + + + +{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/modules/node_content.tpl b/examples/roc_api/site/www/template/html/modules/node_content.tpl new file mode 100644 index 0000000..4825500 --- /dev/null +++ b/examples/roc_api/site/www/template/html/modules/node_content.tpl @@ -0,0 +1,70 @@ +{if condition="html"} + + + + {include file="master2/head.tpl"/} + + +{/if} + +{unless condition="$web"} + + {include file="master2/site_navigation.tpl"/} +{/unless} + +{if condition="html"} + +
+
+
+
+{/if} + + +
+
+
+ +
+ Edit Node Content + +
+
+ +
+
+ +
+
+ +
+ +
+
+
+
+
+{if condition="html"} + +
+
+
+{/if} + + +{if condition="html"} + + + + {include file="master2/optional_enhancement_js.tpl"/} + + + +{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/modules/node_summary.tpl b/examples/roc_api/site/www/template/html/modules/node_summary.tpl new file mode 100644 index 0000000..24f69e6 --- /dev/null +++ b/examples/roc_api/site/www/template/html/modules/node_summary.tpl @@ -0,0 +1,71 @@ +{if condition="html"} + + + + {include file="master2/head.tpl"/} + + +{/if} + + + {unless condition="$web"} + + {include file="master2/site_navigation.tpl"/} + {/unless} + +{if condition="html"} + +
+
+
+
+{/if} + +
+
+
+ +
+ Edit Node Summary + +
+
+ +
+
+ +
+
+ +
+ +
+
+
+
+
+ +{if condition="html"} + +
+
+
+{/if} + + +{if condition="html"} + + + + {include file="master2/optional_enhancement_js.tpl"/} + + + +{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/modules/node_title.tpl b/examples/roc_api/site/www/template/html/modules/node_title.tpl new file mode 100644 index 0000000..2e02d02 --- /dev/null +++ b/examples/roc_api/site/www/template/html/modules/node_title.tpl @@ -0,0 +1,70 @@ +{if condition="html"} + + + + {include file="master2/head.tpl"/} + + +{/if} + + {unless condition="$web"} + + {include file="master2/site_navigation.tpl"/} + {/unless} + + +{if condition="html"} + +
+
+
+
+{/if} + +
+
+
+ +
+ Edit Node Title + +
+
+ +
+
+ +
+
+ +
+ +
+
+
+
+
+{if condition="html"} + +
+
+
+{/if} + + +{if condition="html"} + + + + {include file="master2/optional_enhancement_js.tpl"/} + + + +{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/modules/nodes.tpl b/examples/roc_api/site/www/template/html/modules/nodes.tpl new file mode 100644 index 0000000..23b24c7 --- /dev/null +++ b/examples/roc_api/site/www/template/html/modules/nodes.tpl @@ -0,0 +1,52 @@ +{if condition="html"} + + + + {include file="master2/head.tpl"/} + + +{/if} + +{unless condition="$web"} + + {include file="master2/site_navigation.tpl"/} +{/unless} + +{if condition="html"} + +
+
+
+
+{/if} +
+

List nodes


+ + + {foreach from="$nodes" item="item"} + + {/foreach} +
+ +{if condition="html"} +
+
+
+{/if} + + +{if condition="html"} + + + + {include file="master2/optional_enhancement_js.tpl"/} + + + +{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/template/html/modules/register.tpl b/examples/roc_api/site/www/template/html/modules/register.tpl new file mode 100644 index 0000000..3a14667 --- /dev/null +++ b/examples/roc_api/site/www/template/html/modules/register.tpl @@ -0,0 +1,100 @@ +{if condition="html"} + + + + {include file="master2/head.tpl"/} + + +{/if} + + +{unless condition="$web"} + + {include file="master2/site_navigation.tpl"/} +{/unless} + +{if condition="html"} + +
+
+
+
+{/if} + + +
+
+
+
+ Register +
+

Register new user

+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ s
+ +
+ +
+
+
+
+
+ +{if condition="html"} +
+
+
+{/if} + + +{if condition="html"} + + + + {include file="master2/optional_enhancement_js.tpl"/} + + + +{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/api/layout2.tpl b/examples/roc_api/site/www/themes/api/layout2.tpl new file mode 100644 index 0000000..34a5659 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/layout2.tpl @@ -0,0 +1,40 @@ + + + + {include file="master2/head.tpl"/} + + + + + {include file="master2/site_navigation.tpl"/} + + + +
+
+
+
+ {include file="master2/content.tpl"/} +
+
+
+ + + + {if condition="$web"} + {include file="master2/optional_enhancement_js.tpl"/} + {/if} + + {if condition="$html"} + {include file="master2/optional_enhancement_js.tpl"/} + {/if} + + + + \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/api/master2/content.tpl b/examples/roc_api/site/www/themes/api/master2/content.tpl new file mode 100644 index 0000000..b18c5dd --- /dev/null +++ b/examples/roc_api/site/www/themes/api/master2/content.tpl @@ -0,0 +1,11 @@ + +
+

Top most recent nodes


+ + + {foreach from="$nodes" item="item"} + + {/foreach} +
diff --git a/examples/roc_api/site/www/themes/api/master2/error.tpl b/examples/roc_api/site/www/themes/api/master2/error.tpl new file mode 100644 index 0000000..0ca7ad0 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/master2/error.tpl @@ -0,0 +1,18 @@ +

Error: {$code/}

+ +{assign name="status400" value="400"/} +{assign name="status404" value="404"/} +{assign name="status500" value="500"/} + +{if condition="$code ~ $status500"} +

Internal server error, for the request {$request/}

+{/if} + + +{if condition="$code ~ $status404"} +

Resourse not found, for the request {$request/}

+{/if} + +{if condition="$code ~ $status400"} +

Bad request, the request {$request/} is not valid

+{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/api/master2/footer.tpl b/examples/roc_api/site/www/themes/api/master2/footer.tpl new file mode 100644 index 0000000..11fe183 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/master2/footer.tpl @@ -0,0 +1,7 @@ + +
+

API Documentation     + Questions? Comments? Let us know!

+

© Copyright 2014 Eiffel Software -- Privacy Policy +

+
\ No newline at end of file diff --git a/examples/roc_api/site/www/themes/api/master2/head.tpl b/examples/roc_api/site/www/themes/api/master2/head.tpl new file mode 100644 index 0000000..4ba4616 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/master2/head.tpl @@ -0,0 +1,10 @@ + + +Eiffel RESTonCMS +{if condition="$web"} + {include file="master2/optional_styling_css.tpl"/} +{/if} +{if condition="$html"} + {include file="master2/optional_styling_css.tpl"/} +{/if} + diff --git a/examples/roc_api/site/www/themes/api/master2/header.tpl b/examples/roc_api/site/www/themes/api/master2/header.tpl new file mode 100644 index 0000000..ce8ec71 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/master2/header.tpl @@ -0,0 +1,2 @@ +

RESTonCMS

+

Tagline

\ No newline at end of file diff --git a/examples/roc_api/site/www/themes/api/master2/logoff.tpl b/examples/roc_api/site/www/themes/api/master2/logoff.tpl new file mode 100644 index 0000000..8139dc7 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/master2/logoff.tpl @@ -0,0 +1,5 @@ +

You have successfully signed out

+ +You may want to return + +Press this neat little button:Take Me Home diff --git a/examples/roc_api/site/www/themes/api/master2/main_navigation.tpl b/examples/roc_api/site/www/themes/api/master2/main_navigation.tpl new file mode 100644 index 0000000..88365d7 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/master2/main_navigation.tpl @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/api/master2/optional_enhancement_js.tpl b/examples/roc_api/site/www/themes/api/master2/optional_enhancement_js.tpl new file mode 100644 index 0000000..1353b83 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/master2/optional_enhancement_js.tpl @@ -0,0 +1,5 @@ + + +{if condition="$web"} + +{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/api/master2/optional_styling_css.tpl b/examples/roc_api/site/www/themes/api/master2/optional_styling_css.tpl new file mode 100644 index 0000000..f56d770 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/master2/optional_styling_css.tpl @@ -0,0 +1,9 @@ +{if condition="$html"} + + + +{/if} +{if condition="$web"} + + +{/if} diff --git a/examples/roc_api/site/www/themes/api/master2/site_navigation.tpl b/examples/roc_api/site/www/themes/api/master2/site_navigation.tpl new file mode 100644 index 0000000..a75760c --- /dev/null +++ b/examples/roc_api/site/www/themes/api/master2/site_navigation.tpl @@ -0,0 +1,27 @@ + + + + \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/api/modules/navigation.tpl b/examples/roc_api/site/www/themes/api/modules/navigation.tpl new file mode 100644 index 0000000..ee2d15e --- /dev/null +++ b/examples/roc_api/site/www/themes/api/modules/navigation.tpl @@ -0,0 +1,8 @@ +{if isset="$user"} + Logoff +{/if} +{unless isset="$user"} + Login + Register +{/unless} +List of Nodes diff --git a/examples/roc_api/site/www/themes/api/modules/node.tpl b/examples/roc_api/site/www/themes/api/modules/node.tpl new file mode 100644 index 0000000..0f6173f --- /dev/null +++ b/examples/roc_api/site/www/themes/api/modules/node.tpl @@ -0,0 +1,174 @@ +{if condition="html"} + + + + {include file="master2/head.tpl"/} + + +{/if} + +{unless condition="$web"} + + {include file="master2/site_navigation.tpl"/} +{/unless} + + +{if condition="html"} + +
+
+
+
+{/if} + + +
+ {if condition="$web"} + + {/if} + {if condition="$html"} + + {/if} +
+
+ {if isset="$node"} +
+
+
+
+

{$node.title/}

+
+
+
{$node.content/}
+
+
+
+ {/if} +
+ +
+ {if isset="$user"} +
+
+
+ {if isset="$node"} + +
+ {/if} +
+
+
+ {if isset="$user"} +
+
+ + {if isset="$node"} +
+ +
+ Delete Node + +
+ +
+
+
+ {/if} +
+ {/if} +
+
+
+ +{if condition="html"} +
+
+
+{/if} + + +{if condition="html"} + + + + {include file="master2/optional_enhancement_js.tpl"/} + + + +{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/api/modules/node_content.tpl b/examples/roc_api/site/www/themes/api/modules/node_content.tpl new file mode 100644 index 0000000..4825500 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/modules/node_content.tpl @@ -0,0 +1,70 @@ +{if condition="html"} + + + + {include file="master2/head.tpl"/} + + +{/if} + +{unless condition="$web"} + + {include file="master2/site_navigation.tpl"/} +{/unless} + +{if condition="html"} + +
+
+
+
+{/if} + + +
+
+
+ +
+ Edit Node Content + +
+
+ +
+
+ +
+
+ +
+ +
+
+
+
+
+{if condition="html"} + +
+
+
+{/if} + + +{if condition="html"} + + + + {include file="master2/optional_enhancement_js.tpl"/} + + + +{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/api/modules/node_summary.tpl b/examples/roc_api/site/www/themes/api/modules/node_summary.tpl new file mode 100644 index 0000000..24f69e6 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/modules/node_summary.tpl @@ -0,0 +1,71 @@ +{if condition="html"} + + + + {include file="master2/head.tpl"/} + + +{/if} + + + {unless condition="$web"} + + {include file="master2/site_navigation.tpl"/} + {/unless} + +{if condition="html"} + +
+
+
+
+{/if} + +
+
+
+ +
+ Edit Node Summary + +
+
+ +
+
+ +
+
+ +
+ +
+
+
+
+
+ +{if condition="html"} + +
+
+
+{/if} + + +{if condition="html"} + + + + {include file="master2/optional_enhancement_js.tpl"/} + + + +{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/api/modules/node_title.tpl b/examples/roc_api/site/www/themes/api/modules/node_title.tpl new file mode 100644 index 0000000..2e02d02 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/modules/node_title.tpl @@ -0,0 +1,70 @@ +{if condition="html"} + + + + {include file="master2/head.tpl"/} + + +{/if} + + {unless condition="$web"} + + {include file="master2/site_navigation.tpl"/} + {/unless} + + +{if condition="html"} + +
+
+
+
+{/if} + +
+
+
+ +
+ Edit Node Title + +
+
+ +
+
+ +
+
+ +
+ +
+
+
+
+
+{if condition="html"} + +
+
+
+{/if} + + +{if condition="html"} + + + + {include file="master2/optional_enhancement_js.tpl"/} + + + +{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/api/modules/nodes.tpl b/examples/roc_api/site/www/themes/api/modules/nodes.tpl new file mode 100644 index 0000000..23b24c7 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/modules/nodes.tpl @@ -0,0 +1,52 @@ +{if condition="html"} + + + + {include file="master2/head.tpl"/} + + +{/if} + +{unless condition="$web"} + + {include file="master2/site_navigation.tpl"/} +{/unless} + +{if condition="html"} + +
+
+
+
+{/if} +
+

List nodes


+ + + {foreach from="$nodes" item="item"} + + {/foreach} +
+ +{if condition="html"} +
+
+
+{/if} + + +{if condition="html"} + + + + {include file="master2/optional_enhancement_js.tpl"/} + + + +{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/api/modules/register.tpl b/examples/roc_api/site/www/themes/api/modules/register.tpl new file mode 100644 index 0000000..3a14667 --- /dev/null +++ b/examples/roc_api/site/www/themes/api/modules/register.tpl @@ -0,0 +1,100 @@ +{if condition="html"} + + + + {include file="master2/head.tpl"/} + + +{/if} + + +{unless condition="$web"} + + {include file="master2/site_navigation.tpl"/} +{/unless} + +{if condition="html"} + +
+
+
+
+{/if} + + +
+
+
+
+ Register +
+

Register new user

+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ s
+ +
+ +
+
+
+
+
+ +{if condition="html"} +
+
+
+{/if} + + +{if condition="html"} + + + + {include file="master2/optional_enhancement_js.tpl"/} + + + +{/if} \ No newline at end of file diff --git a/examples/roc_api/site/www/themes/api/theme.info b/examples/roc_api/site/www/themes/api/theme.info new file mode 100644 index 0000000..54b5f6e --- /dev/null +++ b/examples/roc_api/site/www/themes/api/theme.info @@ -0,0 +1,9 @@ +name=api +engine=smarty +author=jvelilla +version=0.1 +regions[header] = Header +regions[content] = Content +regions[footer] = Footer +regions[first_sidebar] = first sidebar +regions[second_sidebar] = second sidebar diff --git a/examples/roc_api/site/www/themes/smarty/front-page.tpl b/examples/roc_api/site/www/themes/smarty/front-page.tpl new file mode 100644 index 0000000..ae932ee --- /dev/null +++ b/examples/roc_api/site/www/themes/smarty/front-page.tpl @@ -0,0 +1,12 @@ +{include file="tpl/page-header.tpl"/} +
+
+ +
+ Welcome ... this is the front page + {if isset="$content"}{$content/}{/if} +
+ +
+
+{include file="tpl/page-footer.tpl"/} diff --git a/examples/roc_api/site/www/themes/smarty/page.tpl b/examples/roc_api/site/www/themes/smarty/page.tpl new file mode 100644 index 0000000..5dde43c --- /dev/null +++ b/examples/roc_api/site/www/themes/smarty/page.tpl @@ -0,0 +1,11 @@ +{include file="tpl/page-header.tpl"/} +
+
+ +
+ {if isset="$content"}{$content/}{/if} +
+ +
+
+{include file="tpl/page-footer.tpl"/} diff --git a/examples/roc_api/site/www/themes/smarty/res/ewfcms.js b/examples/roc_api/site/www/themes/smarty/res/ewfcms.js new file mode 100644 index 0000000..d4ebbef --- /dev/null +++ b/examples/roc_api/site/www/themes/smarty/res/ewfcms.js @@ -0,0 +1,91 @@ +/* + * EWF CMS javascript based on JQuery + */ + +/** + * Override jQuery.fn.init to guard against XSS attacks. + * + * See http://bugs.jquery.com/ticket/9521 + */ + +(function () { + var jquery_init = jQuery.fn.init; + jQuery.fn.init = function (selector, context, rootjQuery) { + // If the string contains a "#" before a "<", treat it as invalid HTML. + if (selector && typeof selector === 'string') { + var hash_position = selector.indexOf('#'); + if (hash_position >= 0) { + var bracket_position = selector.indexOf('<'); + if (bracket_position > hash_position) { + throw 'Syntax error, unrecognized expression: ' + selector; + } + } + } + return jquery_init.call(this, selector, context, rootjQuery); + }; + jQuery.fn.init.prototype = jquery_init.prototype; +})(); + + +var EWFCMS = EWFCMS || { }; + +EWFCMS.toggleFieldset = function(fieldset) { + if ($(fieldset).is('.collapsed')) { + var content = $('> div:not(.action)', fieldset); + $(fieldset).removeClass('collapsed'); + content.hide(); + content.slideDown( { + duration: 'fast', + easing: 'linear', + complete: function() { + //Drupal.collapseScrollIntoView(this.parentNode); + this.parentNode.animating = false; + $('div.action', fieldset).show(); + }, + step: function() { + // Scroll the fieldset into view + //Drupal.collapseScrollIntoView(this.parentNode); + } + }); + } else { + var content = $('> div:not(.action)', fieldset).slideUp('fast', function() { + $(this.parentNode).addClass('collapsed'); + this.parentNode.animating = false; + }); + } + }; + +jQuery(document).ready(function(){ + //$('.collapsed').hide(); + $('fieldset.collapsible > legend').each(function() { + var fieldset = $(this.parentNode); + // turn legen into clickable link and wrap contents + var text = this.innerHTML; + $(this).empty() + .append($(''+ text + '').click(function() { + var fieldset = $(this).parents('fieldset:first')[0]; + if (!fieldset.animating) { + fieldset.animating = true; + EWFCMS.toggleFieldset(fieldset); + } + return false; + } + )) + .after($('
') + .append(fieldset.children(':not(legend):not(.action)'))) + .addClass('collapse-processed'); + }); + $('fieldset.collapsed').each(function() { + $(this).removeClass('collapsed'); + EWFCMS.toggleFieldset(this); + }); +}); + +jQuery(document).ready(function(){ + $('#tabs').tabs(); +}); + +//jQuery(document).ready(function(){ + //$('#second_sidebar').hide(); +//}); + diff --git a/examples/roc_api/site/www/themes/smarty/res/favicon.ico b/examples/roc_api/site/www/themes/smarty/res/favicon.ico new file mode 100644 index 0000000..343067f Binary files /dev/null and b/examples/roc_api/site/www/themes/smarty/res/favicon.ico differ diff --git a/examples/roc_api/site/www/themes/smarty/res/logo.png b/examples/roc_api/site/www/themes/smarty/res/logo.png new file mode 100644 index 0000000..d797376 Binary files /dev/null and b/examples/roc_api/site/www/themes/smarty/res/logo.png differ diff --git a/examples/roc_api/site/www/themes/smarty/res/menu-collapsed.png b/examples/roc_api/site/www/themes/smarty/res/menu-collapsed.png new file mode 100644 index 0000000..95a214a Binary files /dev/null and b/examples/roc_api/site/www/themes/smarty/res/menu-collapsed.png differ diff --git a/examples/roc_api/site/www/themes/smarty/res/menu-expanded.png b/examples/roc_api/site/www/themes/smarty/res/menu-expanded.png new file mode 100644 index 0000000..46f39ec Binary files /dev/null and b/examples/roc_api/site/www/themes/smarty/res/menu-expanded.png differ diff --git a/examples/roc_api/site/www/themes/smarty/res/style.css b/examples/roc_api/site/www/themes/smarty/res/style.css new file mode 100644 index 0000000..b0615ae --- /dev/null +++ b/examples/roc_api/site/www/themes/smarty/res/style.css @@ -0,0 +1,251 @@ +body { margin: 0; background-color: #eeeeff;} +div#header { background-color: #003; color: #fff; border: solid 1px #003; padding: 0px; margin: 0px;} +div#header img#logo { float: left; margin: 5px 15px 5px 10px; } +div#header div#title {font-size: 180%; font-weight: bold; margin-top: 10px; } +ul.horizontal { + list-style-type: none; +} +ul.horizontal li { + display: inline; + padding: 0 5px 0 5px; +} + +div#menu-bar li.active { + border: solid 1px #ff0; + color: #ff0; +} +div#menu-bar li:hover { + background-color: #fff; + color: #00f; +} +div#menu-bar li a { + text-decoration: none; + color: #fff; +} +div#menu-bar li:hover a { + color: #00f; + font-style: bold; +} + + +div#primary-tabs li { + color: #00f; + padding: 2px 5px 2px 5px; + background-color: #eee; + border: solid 1px #ccf; +} +div#primary-tabs li.active { + padding: 2px 7px 1px 7px; + border-top: solid 2px #99f; + border-left: solid 1px #99f; + border-right: solid 1px #99f; + border-bottom: 0; + background-color: #fff; + color: #00f; +} +div#primary-tabs li:hover { + background-color: #fff; + color: #00f; +} +div#primary-tabs li a { + text-decoration: none; + color: #00f; +} +div#primary-tabs li:hover a { + color: #00f; + font-style: bold; +} + + + +div#menu-first { margin-left: 20%; color: #ccf; background-color: #003; } +div#menu-first a { color: #ccf; } +div#menu-second { color: #99f; background-color: #333; } +div#menu-second a { color: #99f; } + +div#main-wrapper { + clear: both; + display: block; + height: 0; +} +div#main { margin: 0; padding: 0; clear: both; height:0; display: block; } + +div#content { + padding: 5px 3px 5px 20px; + margin-top: 10px; + min-width: 60%; + display: inline; + float: left; + position: relative; + background-color: #ffffff; + padding-bottom: 30px; +} + +div#first_sidebar { + width: 20%; + margin: 5px; + padding: 5px; + display: inline; + float: left; + position: relative; +} +div#second_sidebar { + width: 20%; + margin: 5px; + padding: 5px; + display: inline; + float: left; + position: relative; + background-color: #eee; +} +div.sidebar div.block { + margin-bottom: 5px; + padding: 0; + border: dotted 1px #999; + background-color: #fff; +} +div.sidebar div.block div.title { + padding: 3px 3px 3px 3px; + font-weight: bold; + background-color: #dedede; + border-bottom: dotted 1px #999; +} +div.sidebar div.block div.inside { + margin: 3px; +} +div#footer { margin: 10px 0 10px 0; clear: both; display: block; text-align: center; padding: 10px; border-top: solid 1px #00f; color: #fff; background-color: #333;} +div#footer a { color: #ff0; } + +form div.error { + border-top: dotted 1px #f00; + border-bottom: dotted 1px #f00; + border-left: solid 3px #f00; +} +div.node div.title { + font-weight: bold; + font-size: 110%; + border-bottom: dotted 1 px #009; +} +div.description { + font-style: italic; + font-color: #999; +} + +div.node-wrapper { + margin: 5px 2px 5px 2px; + border: dotted 1px #dddddd; + padding: 5px 3px 5px 3px; +} +div.node div.title { + font-weight: bold; + font-size: 110%; + border-bottom: dotted 1 px #009; + float: left; +} +div.node div.description { + text-align: right; +} +div.node div.inner { + padding: 5px 5px 5px 10px; + border-top: dotted 1px #dddddd; +} + +form#user-login { + border: dotted 1px #099; + display: inline-block; + padding: 10px; + margin: 10px; +} + +form#user-login>div { + margin-bottom: 10px; +} +form#user-login .input { + float: left; +} +form#user-login img.logo { +} + +div#message { + border: solid 1px #fc0; + background-color: #fed; + color: #000; + padding: 5px; + margin: 5px; +} + +div#message li { + padding-left: 5px; + margin-left: 3px; +} +div#message li.success { + color: #003300; + background-color: #ccffcc; +} + +div#message li.error { + color: #330000; + background-color: #ff9494; +} +div#message li.warning { + color: #aa2200; + background-color: #ffcc99; +} + +div.columns { + margin-top: 10px; + display: inline-block; + clear: both; +} + +div.columns>* { + padding-left: 10px; + padding-top: 5px; + border-top: dotted 1px #999; + border-left: dotted 1px #999; + margin-left: 1px; + margin-right: 10px; + float: left; +} + +/* Link */ + +a { + text-decoration: none; +} +a:hover { + text-decoration: underline; +} + +div.menu ul.vertical { + margin: 0; + padding-left: 10px; + list-style-type: none; +} + +div.menu ul.vertical ul { + border-left: solid 3px #eee; + list-style-type: none; + margin: 0; + padding-left: 5px; + margin-left: 5px; + margin-bottom: 5px; +} + +/* Fieldset and collapsible */ + +fieldset.collapsible legend a { + padding-left: 15px; + background: url(menu-expanded.png) 5px 75% no-repeat; +} + +fieldset.collapsed legend a { + padding-left: 15px; + background: url(menu-collapsed.png) 5px 50% no-repeat; +} + +fieldset.collapsed { + border: none; + border-top: dotted 1px #000; +} + diff --git a/examples/roc_api/site/www/themes/smarty/theme.info b/examples/roc_api/site/www/themes/smarty/theme.info new file mode 100644 index 0000000..38a712a --- /dev/null +++ b/examples/roc_api/site/www/themes/smarty/theme.info @@ -0,0 +1,10 @@ +name=smarty +engine=smarty +author=jfiat +version=0.1 +;template_dir=templates +regions[header] = Header +regions[content] = Content +regions[footer] = Footer +regions[first_sidebar] = first sidebar +regions[second_sidebar] = second sidebar diff --git a/examples/roc_api/site/www/themes/smarty/tpl/page-footer.tpl b/examples/roc_api/site/www/themes/smarty/tpl/page-footer.tpl new file mode 100644 index 0000000..693215b --- /dev/null +++ b/examples/roc_api/site/www/themes/smarty/tpl/page-footer.tpl @@ -0,0 +1,6 @@ + + + +{if isset="$page_bottom"}{$page_bottom/}{/if} + + diff --git a/examples/roc_api/site/www/themes/smarty/tpl/page-header.tpl b/examples/roc_api/site/www/themes/smarty/tpl/page-header.tpl new file mode 100644 index 0000000..c8eba5a --- /dev/null +++ b/examples/roc_api/site/www/themes/smarty/tpl/page-header.tpl @@ -0,0 +1,14 @@ + + + +{if isset="$head"}{$head/}{/if} +{$head_title/} +{if isset="$styles"}{$styles/}{/if} +{if isset="$scripts"}{$scripts/}{/if} +{if isset="$head_lines"}{$head_lines/}{/if} + +
+
+ diff --git a/examples/roc_api/src/ewf_roc_server.e b/examples/roc_api/src/ewf_roc_server.e new file mode 100644 index 0000000..4f16373 --- /dev/null +++ b/examples/roc_api/src/ewf_roc_server.e @@ -0,0 +1,139 @@ +note + description: "[ + application service + ]" + date: "$Date$" + revision: "$Revision$" + +class + EWF_ROC_SERVER + +inherit + WSF_LAUNCHABLE_SERVICE + rename + make_and_launch as make_and_launch_service + redefine + initialize + end + WSF_SERVICE + redefine + execute + end + + REFACTORING_HELPER + + ARGUMENTS + + SHARED_LOGGER + +create + make_and_launch + +feature {NONE} -- Initialization + + make_and_launch + do + create launcher + make_and_launch_service + end + + initialize + -- Initialize current service. + do + Precursor + service_options := create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI}.make_from_file ("roc.ini") + launch_cms (cms_setup) + end + +feature -- Service + + cms_service: CMS_SERVICE + -- cms service. + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + do + cms_service.execute (req, res) + end + +feature -- Layout + + layout: CMS_LAYOUT + -- cms layout + +feature {NONE} -- Launch operation + + launcher: APPLICATION_LAUNCHER + + launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + local + l_retry: BOOLEAN + l_message: STRING + do + if not l_retry then + log.write_debug (generator + ".launch") + launcher.launch (a_service, opts) + else + -- error hanling. + create l_message.make (1024) + if attached ((create {EXCEPTION_MANAGER}).last_exception) as l_exception then + if attached l_exception.description as l_description then + l_message.append (l_description.as_string_32) + l_message.append ("%N%N") + elseif attached l_exception.trace as l_trace then + l_message.append (l_trace) + l_message.append ("%N%N") + else + l_message.append (l_exception.out) + l_message.append ("%N%N") + end + else + l_message.append ("The application crash without available information") + l_message.append ("%N%N") + end + -- send email shutdown + log.write_debug (generator + ".launch shutdown") + end + rescue + l_retry := True + retry + end + +feature -- CMS Initialization + + cms_setup: CMS_CUSTOM_SETUP + do + if attached separate_character_option_value ('d') as l_dir then + log.write_debug (generator + ".cms_setup using a command line argument -d " + l_dir ) + create layout.make_with_path (create {PATH}.make_from_string (l_dir)) + else + log.write_debug (generator + ".cms_setup using current directory" ) + create layout.make_default + end + create Result.make (layout) + setup_modules (Result) + setup_storage (Result) + end + + launch_cms (a_setup: CMS_SETUP) + local + cms: CMS_SERVICE + do + log.write_debug (generator + ".launch_cms") + create cms.make (a_setup) + cms_service := cms + end + +feature -- CMS setup + + setup_modules (a_setup: CMS_SETUP) + -- Setup modules to be added to the CMS ecosystem. + do + to_implement ("To implement custom modules") + end + + setup_storage (a_setup: CMS_SETUP) + do + + end +end + diff --git a/layout/src/error/error_handler.e b/layout/src/error/basic_error_handler.e similarity index 98% rename from layout/src/error/error_handler.e rename to layout/src/error/basic_error_handler.e index 2977f0a..3c29d2c 100644 --- a/layout/src/error/error_handler.e +++ b/layout/src/error/basic_error_handler.e @@ -4,7 +4,7 @@ note revision: "$Revision: 95678 $" class - ERROR_HANDLER + BASIC_ERROR_HANDLER create make diff --git a/layout/src/error/shared_error.e b/layout/src/error/shared_error.e index 3b0cfb9..82c87b6 100644 --- a/layout/src/error/shared_error.e +++ b/layout/src/error/shared_error.e @@ -12,7 +12,7 @@ inherit feature -- Access - last_error: detachable ERROR_HANDLER + last_error: detachable BASIC_ERROR_HANDLER -- Object represent last error. last_error_message: READABLE_STRING_32 @@ -82,7 +82,7 @@ feature -- Element Settings failed: not successful end - set_last_error_from_handler (a_error: detachable ERROR_HANDLER) + set_last_error_from_handler (a_error: detachable BASIC_ERROR_HANDLER) -- Set `last_error' with `a_error'. do last_error := a_error diff --git a/persistence/Readme.md b/persistence/Readme.md new file mode 100644 index 0000000..e69de29 diff --git a/persistence/implementation/common/database/database_error_handler.e b/persistence/implementation/common/database/database_error_handler.e new file mode 100644 index 0000000..a2718fe --- /dev/null +++ b/persistence/implementation/common/database/database_error_handler.e @@ -0,0 +1,35 @@ +note + description: "Database error handler" + date: "$Date: 2013-08-08 16:39:49 -0300 (ju. 08 de ago. de 2013) $" + revision: "$Revision: 195 $" + +class + DATABASE_ERROR_HANDLER + +inherit + ERROR_HANDLER + +create + make + +feature -- Error operation + + add_database_error (a_message: READABLE_STRING_32; a_code: INTEGER) + -- Add a database error + local +-- l_error: DATABASE_ERROR + do +-- create l_error.make_from_message (a_message, a_code) +-- add_error (l_error) + end + + add_database_no_change_error (a_message: READABLE_STRING_32; a_code: INTEGER) + -- Add a database error + local +-- l_error: DATABASE_NO_CHANGE_ERROR + do +-- create l_error.make_from_message (a_message, a_code) +-- add_error (l_error) + end + +end diff --git a/persistence/implementation/common/database/database_storage_manager.e b/persistence/implementation/common/database/database_storage_manager.e new file mode 100644 index 0000000..e59ef5a --- /dev/null +++ b/persistence/implementation/common/database/database_storage_manager.e @@ -0,0 +1,371 @@ +note + description: "[ + Manager to initialize data api for database access, + create database connection and so on + ]" + date: "$Date: 2013-08-08 16:39:49 -0300 (ju. 08 de ago. de 2013) $" + revision: "$Revision: 195 $" + +class + DATABASE_STORAGE_MANAGER + +inherit + GLOBAL_SETTINGS + + REFACTORING_HELPER + + SHARED_ERROR_HANDLER + +create + make + +feature -- Initialization + + make (a_data_app: like data_app; a_database_name: like database_name; a_name: like name; a_password: like password; + a_host_name: like host_name; a_role_id: like role_id; a_role_password: like role_password + a_data_source: like data_source; a_group: like group) + -- Initialize with login info. + -- + -- `a_database_name' is used for MySQL + -- `a_name', the login user name + -- `a_password', the login user password, unencrypted. + local + l_storage: STRING_8 + do + create l_storage.make (64) + storage_url := l_storage + l_storage.append (a_data_app.db_spec.database_handle_name.as_lower) + l_storage.append ("://") + + data_app := a_data_app + database_name := a_database_name + name := a_name + password := a_password + host_name := a_host_name + role_id := a_role_id + role_password := a_role_password + data_source := a_data_source + group := a_group + + set_use_extended_types (True) + set_map_zero_null_value (False) + + l_storage.append (a_name.as_string_8) + l_storage.append (":********@") + if a_host_name /= Void then + a_data_app.set_hostname (a_host_name) + l_storage.append (a_host_name) + end + + if a_database_name /= Void then + a_data_app.set_application (a_database_name.as_string_8) + l_storage.append ("/" + a_database_name.as_string_8) + end + + if a_data_source /= Void then + a_data_app.set_data_source (a_data_source) + end + if a_role_id /= Void and then a_role_password /= Void then + a_data_app.set_role (a_role_id, a_role_password) + end + if a_group /= Void then + a_data_app.set_group (a_group) + end + + a_data_app.login (a_name.as_string_8, a_password.as_string_8) + a_data_app.set_base + + create session_control.make + + end + + report_database_schema_incompatibility (a_output: BOOLEAN) + -- Report the application code is not compatible with database schema version + -- if `a_output' is True, write error in io.error as well + require +-- incompatible_database_schema_version: not is_database_schema_version_compatible + local + db_v: READABLE_STRING_8 + do +-- if attached database_schema_version as v then +-- db_v := v.version +-- else +-- db_v := "?.?.?.?" +-- end +-- database_error_handler.add_error_details (0, "MISC Error", "Schema version incompatible (application=" +-- + database_storage_version.version + " database=" + db_v + ")." +-- ) + if a_output then + io.error.put_string (database_error_handler.as_string_representation) + io.error.put_new_line + end + end + +feature -- System Update + + update_system + do +-- if is_database_schema_version_compatible then +-- misc_manager.initialize_reference_types +-- history_manager.initialize_data +-- user_role_permission_manager.initialize_built_in_user_role_permission +-- user_role_permission_manager.initialize_extra_user_role_permission +-- task_manager.initialize_data +-- else +-- -- If schema incompatible, report it and exit +-- report_database_schema_incompatibility (True) +-- (create {EXCEPTIONS}).die (-1) +-- end + +-- [2012-Mars-21] Idea about update system implementation +-- if update_version < 01.00.0012 then +-- if update_version < 01.00.0005 then +-- update_version_01_00_0005 +-- end +-- update_version_01_00_0012 +-- end + end + + reset_storage_manager + do +-- initialize_managers (Current) + end + +feature -- Storage + + storage_url: READABLE_STRING_8 + -- Associated storage URL + + storage_connection_kept_alive: BOOLEAN + -- Keep storage connection alive? + -- i.e: never disconnect between 2 transactions. + + keep_storage_connection_alive (b: BOOLEAN) + do + storage_connection_kept_alive := b + end + + connect_storage + -- Connect the database + do + if not session_control.is_connected then + session_control.connect + end + end + + disconnect_from_storage + -- Disconnect from the storage + require + is_connected_to_storage: is_connected_to_storage + do + if not storage_connection_kept_alive then + session_control.disconnect + end + end + + force_disconnect_from_storage + -- Force disconnection from the storage + -- i.e ignore any `storage_connection_kept_alive' + do + if session_control.is_connected then + session_control.disconnect + end + end + + is_connected_to_storage: BOOLEAN + -- Is connected to the database + do + Result := session_control.is_connected + end + +feature -- Transaction Status + + in_transaction_session: BOOLEAN + -- Is session started? + + transaction_session_depth: INTEGER + -- Depth in the transaction session + +feature -- Transaction Operation + + start_transaction_session + -- Start session + -- if already started, increase the `transaction_session_depth' + require + in_transaction_session implies transaction_session_depth > 0 + not in_transaction_session implies transaction_session_depth = 0 + local + l_session_control: like session_control + l_retried: INTEGER + do + if l_retried = 0 then + if not in_transaction_session then + database_error_handler.reset + + check transaction_session_depth = 0 end + + debug ("database_session") + print ("..Start session%N") + end + connect_storage -- connect the DB + if is_connected_to_storage then + in_transaction_session := True + session_control.begin -- start transaction + else + l_session_control := session_control + if not l_session_control.is_ok then + database_error_handler.add_database_error (l_session_control.error_message_32, l_session_control.error_code) + else + database_error_handler.add_database_error (Session_not_started_error_message, 0) + end + l_session_control.reset + end + end + transaction_session_depth := transaction_session_depth + 1 + else + if l_retried = 1 then + transaction_session_depth := transaction_session_depth + 1 + if attached (create {EXCEPTION_MANAGER}).last_exception as e then + if attached {ASSERTION_VIOLATION} e then + --| Ignore for now with MYSQL ... + else + exception_as_error (e) + end + end + + in_transaction_session := False + session_control.reset + else + in_transaction_session := False + end + end + ensure + transaction_session_depth = (old transaction_session_depth) + 1 + rescue + l_retried := l_retried + 1 + retry + end + + end_transaction_session + -- End session + local + l_retried: BOOLEAN + do + if not l_retried then + transaction_session_depth := transaction_session_depth - 1 + if transaction_session_depth = 0 then + debug ("database_session") + print ("..End session%N") + end + if is_connected_to_storage then + if not database_error_handler.has_error then + session_control.commit -- Commit transaction + else + session_control.rollback -- Rollback transaction + end + disconnect_from_storage + end + in_transaction_session := False + end + else + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + in_transaction_session := False + transaction_session_depth := transaction_session_depth - 1 + session_control.reset + end + rescue + l_retried := True + retry + end + + execute_query (a_query: STRING_32) + -- Execute `a_q' + require + is_session_started: in_transaction_session + local + rescued: BOOLEAN + l_change: like new_database_change + do + if not rescued then + session_control.reset + l_change := new_database_change + l_change.set_query (a_query) + l_change.execute_query + else + database_error_handler.add_error_details (0, "Unexpected Error", "Unexpected Error when executing query") + end + rescue + rescued := True + retry + end + +feature -- Element Change + + set_last_inserted_id_function (a_f: like last_inserted_id_function) + -- Set `last_inserted_id_function' with `a_f' + do + last_inserted_id_function := a_f + ensure + last_inserted_id_function_set: last_inserted_id_function = a_f + end + +feature -- Access + + database_name: detachable READABLE_STRING_GENERAL + -- Database to access + + name: READABLE_STRING_GENERAL + -- Login user name + + password: READABLE_STRING_8 + -- Password + + host_name: detachable READABLE_STRING_8 + -- Host name, and port if needed + + role_id: detachable READABLE_STRING_8 + -- Role id + + role_password: detachable READABLE_STRING_8 + -- Role password + + data_source: detachable READABLE_STRING_8 + -- Data source + + group: detachable READABLE_STRING_8 + -- Group + + data_app: DATABASE_APPL [DATABASE] + -- Database application + + last_inserted_id_function: detachable FUNCTION [ANY, TUPLE, NATURAL_64] + -- Function to get last inserted id. + +feature -- Factory + + new_database_change: DB_CHANGE + -- Database change + do + create Result.make + end + + new_database_selection: DB_SELECTION + -- Database selection + do + create Result.make + end + + new_procedure (a_name: like {DB_PROC}.name): DB_PROC + -- Database procedure + do + create Result.make (a_name) + end + +feature {NONE} -- Implementation + + session_not_started_error_message: STRING_32 = "Session could not be started for unknown reason" + + session_control: DB_CONTROL + -- Session + +end diff --git a/persistence/implementation/common/database/shared_error_handler.e b/persistence/implementation/common/database/shared_error_handler.e new file mode 100644 index 0000000..9c26bfd --- /dev/null +++ b/persistence/implementation/common/database/shared_error_handler.e @@ -0,0 +1,27 @@ +note + description: "Shared error handler for database" + date: "$Date: 2013-08-08 16:39:49 -0300 (ju. 08 de ago. de 2013) $" + revision: "$Revision: 195 $" + +class + SHARED_ERROR_HANDLER + +feature -- Access + + database_error_handler: DATABASE_ERROR_HANDLER + -- Error handler + once + create Result.make + end + +feature -- Helper + + exception_as_error (a_e: like {EXCEPTION_MANAGER}.last_exception) + -- Record exception as an error. + do + if attached a_e as l_e and then attached l_e.exception_trace as l_trace then + database_error_handler.add_error_details (l_e.code, once "Exception", l_trace.as_string_32) + end + end + +end diff --git a/persistence/implementation/mysql/persistence_mysql.ecf b/persistence/implementation/mysql/persistence_mysql.ecf index 4577af1..8b0e9aa 100644 --- a/persistence/implementation/mysql/persistence_mysql.ecf +++ b/persistence/implementation/mysql/persistence_mysql.ecf @@ -10,6 +10,8 @@ + +