nurpawiki-1.2.3/0000755000175000017500000000000011251252514014266 5ustar jhellstenjhellstennurpawiki-1.2.3/history.ml0000644000175000017500000001764011072131045016325 0ustar jhellstenjhellsten(* Copyright (c) 2006-2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) module P = Printf open XHTML.M open Eliom_sessions open Eliom_parameters open Eliom_services open Eliom_predefmod.Xhtml open Lwt open ExtList open ExtString open Services open Types open Util open CalendarLib module Db = Database let n_log_items_per_page = 300 let descr_of_activity_type = function AT_create_todo -> "Created" | AT_complete_todo -> "Completed" | AT_work_on_todo -> "Worked on" | AT_create_page -> "Created" | AT_edit_page -> "Edited" | AT_uncomplete_todo -> "Resurrected" module ReverseOrdString = struct type t = String.t let compare a b = String.compare b a end module RSMap = Map.Make (ReverseOrdString) type act_group = { ag_created_todos : (string * string * page list) list; ag_completed_todos : (string * string * page list) list; ag_resurrected_todos : (string * string * page list) list; ag_edited_pages : page list; ag_page_editors : string list; } let empty_act_group = { ag_created_todos = []; ag_completed_todos = []; ag_resurrected_todos = []; ag_page_editors = []; ag_edited_pages = []; } let group_activities activities activity_in_pages = List.fold_left (fun acc a -> let date = date_of_date_time_string a.a_date in let d = Printer.DatePrinter.sprint "%Y-%m-%d" date in let ag = try RSMap.find d acc with Not_found -> empty_act_group in let pages = try IMap.find a.a_id activity_in_pages with Not_found -> [] in let opt_to_str o = Option.default "" o in let ag' = let changed_by = opt_to_str a.a_changed_by in match a.a_activity with AT_create_todo -> (match a.a_todo_descr with Some descr -> let e = (descr, changed_by, pages)::ag.ag_created_todos in { ag with ag_created_todos = e } | None -> P.eprintf "no descr in activity_log %i\n" a.a_id; ag) | AT_complete_todo -> (match a.a_todo_descr with Some descr -> let e = (descr, changed_by, pages)::ag.ag_completed_todos in { ag with ag_completed_todos = e } | None -> P.eprintf "no descr in activity_log %i\n" a.a_id; ag) | AT_uncomplete_todo -> (match a.a_todo_descr with Some descr -> let e = (descr, changed_by, pages)::ag.ag_resurrected_todos in { ag with ag_resurrected_todos = e } | None -> P.eprintf "no descr in activity_log %i\n" a.a_id; ag) | AT_create_page | AT_edit_page -> let add_editor e acc = if List.mem e acc then acc else e::acc in { ag with ag_page_editors = add_editor changed_by ag.ag_page_editors; ag_edited_pages = pages @ ag.ag_edited_pages } | AT_work_on_todo -> ag in RSMap.add d ag' acc) RSMap.empty activities let remove_duplicates strs = let module PSet = Set.Make (struct type t = page let compare a b = compare a.p_descr b.p_descr end) in let s = List.fold_left (fun acc e -> PSet.add e acc) PSet.empty strs in PSet.fold (fun e acc -> e::acc) s [] let page_links sp cur_page max_pages = let links = ref [] in for i = 0 to max_pages do let p = string_of_int i in let link = if cur_page = i then strong [pcdata p] else a ~sp ~service:history_page [pcdata p] (Some i) in links := link :: pcdata " " :: !links done; pcdata "More pages: " :: List.rev !links let view_history_page sp ~conn ~cur_user ~nth_page = let highest_log_id = Database.query_highest_activity_id ~conn in (* max_id is inclusive, min_id exclusive, hence 1 and 0 *) let max_id = max 1 (highest_log_id - nth_page * n_log_items_per_page) in let min_id = max 0 (max_id - n_log_items_per_page) in let n_total_pages = highest_log_id / n_log_items_per_page in let activity = Database.query_past_activity ~conn ~min_id ~max_id in let activity_in_pages = Database.query_activity_in_pages ~conn ~min_id ~max_id in let prettify_date d = let d = date_of_date_time_string d in Printer.DatePrinter.sprint "%a %b %d, %Y" d in let activity_groups = group_activities activity activity_in_pages in let act_table = table ~a:[a_class ["todo_table"]] (tr (th []) [th [pcdata "Activity"]; th [pcdata "By"]; th [pcdata "Details"]]) (List.rev (fst (RSMap.fold (fun date e (lst_acc,prev_date) -> let prettified_date = prettify_date date in let date_text = if prev_date = prettified_date then [] else [pcdata prettified_date] in let todo_html ty lst = List.rev (List.mapi (fun ndx (todo,changed_by,pages) -> (tr (td []) [td (if ndx = 0 then [pcdata ty] else []); td ~a:[a_class ["todo_owner"]] [pcdata changed_by]; td ([pcdata todo] @ (Html_util.todo_page_links_of_pages ~colorize:true sp pages))])) lst) in let created_todos = todo_html "Created" e.ag_created_todos in let completed_todos = todo_html "Completed" e.ag_completed_todos in let resurrected_todos = todo_html "Resurrected" e.ag_resurrected_todos in let pages_html = if e.ag_edited_pages <> [] then [tr (td []) [td [pcdata "Edited"]; td ~a:[a_class ["todo_owner"]] [pcdata (String.concat "," e.ag_page_editors)]; td (Html_util.todo_page_links_of_pages sp ~colorize:true ~insert_parens:false (remove_duplicates e.ag_edited_pages))]] else [] in (* NOTE: 'tr' comes last as we're building the page in reverse order *) (pages_html @ created_todos @ completed_todos @ resurrected_todos @ [tr (td ~a:[a_class ["no_break"; "h_date_heading"]] date_text) []] @ lst_acc, prettified_date)) activity_groups ([],"")))) in Html_util.html_stub sp (Html_util.navbar_html sp ~cur_user ([h1 [pcdata "Blast from the past"]] @ (page_links sp nth_page n_total_pages) @ [br (); br ()] @ [act_table])) (* /history *) let _ = register history_page (fun sp nth_page () -> Session.with_guest_login sp (fun cur_user sp -> let page = Option.default 0 nth_page in Db.with_conn (fun conn -> view_history_page sp ~conn ~cur_user ~nth_page:page))) nurpawiki-1.2.3/database_schema.ml0000644000175000017500000001016611073220071017703 0ustar jhellstenjhellsten(* Copyright (c) 2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) module Psql = Postgresql open Database let install_schema ~conn = let sql = " -- -- PostgreSQL database dump -- SET client_encoding = 'UTF8'; SET standard_conforming_strings = off; SET check_function_bodies = false; SET client_min_messages = warning; SET escape_string_warning = off; SET search_path TO public, pg_catalog; -- -- Name: findwikipage_t; Type: TYPE; Schema: public; Owner: - -- CREATE TYPE findwikipage_t AS ( page_id bigint, headline text, rank real ); CREATE FUNCTION findwikipage(text) RETURNS SETOF findwikipage_t AS $_$ SELECT page_id, ts_headline(page_text, q), ts_rank(page_searchv, q) FROM wikitext, to_tsquery($1) AS q WHERE page_searchv @@ q ORDER BY ts_rank(page_searchv, q) DESC$_$ LANGUAGE sql; SET default_tablespace = ''; SET default_with_oids = false; CREATE TABLE activity_in_pages ( activity_log_id bigint NOT NULL, page_id bigint NOT NULL ); CREATE TABLE activity_log ( id integer NOT NULL, activity_timestamp timestamp without time zone DEFAULT now(), activity_id bigint NOT NULL, todo_id bigint ); CREATE SEQUENCE activity_log_id_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1; ALTER SEQUENCE activity_log_id_seq OWNED BY activity_log.id; CREATE TABLE pages ( id integer NOT NULL, page_descr character varying(256) ); CREATE SEQUENCE pages_id_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1; ALTER SEQUENCE pages_id_seq OWNED BY pages.id; SET default_with_oids = true; SET default_with_oids = false; CREATE TABLE todos ( id integer NOT NULL, completed boolean DEFAULT false, created timestamp without time zone DEFAULT now(), priority integer DEFAULT 3, descr text, activation_date date DEFAULT now(), CONSTRAINT todos_priority CHECK ((((priority = 1) OR (priority = 2)) OR (priority = 3))) ); CREATE SEQUENCE todos_id_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1; ALTER SEQUENCE todos_id_seq OWNED BY todos.id; CREATE TABLE todos_in_pages ( todo_id bigint NOT NULL, page_id bigint NOT NULL ); CREATE TABLE wikitext ( page_id bigint, page_text text, page_searchv tsvector ); ALTER TABLE activity_log ALTER COLUMN id SET DEFAULT nextval('activity_log_id_seq'::regclass); ALTER TABLE pages ALTER COLUMN id SET DEFAULT nextval('pages_id_seq'::regclass); ALTER TABLE todos ALTER COLUMN id SET DEFAULT nextval('todos_id_seq'::regclass); ALTER TABLE ONLY activity_log ADD CONSTRAINT activity_log_pkey PRIMARY KEY (id); ALTER TABLE ONLY pages ADD CONSTRAINT pages_pkey PRIMARY KEY (id); ALTER TABLE ONLY todos ADD CONSTRAINT todos_pkey PRIMARY KEY (id); CREATE INDEX wikitext_index ON wikitext USING gist (page_searchv); ALTER TABLE ONLY todos_in_pages ADD CONSTRAINT \"$1\" FOREIGN KEY (todo_id) REFERENCES todos(id); ALTER TABLE ONLY activity_in_pages ADD CONSTRAINT \"$1\" FOREIGN KEY (activity_log_id) REFERENCES activity_log(id); ALTER TABLE ONLY activity_log ADD CONSTRAINT \"$2\" FOREIGN KEY (todo_id) REFERENCES todos(id); ALTER TABLE ONLY todos_in_pages ADD CONSTRAINT \"$2\" FOREIGN KEY (page_id) REFERENCES pages(id); ALTER TABLE ONLY activity_in_pages ADD CONSTRAINT \"$2\" FOREIGN KEY (page_id) REFERENCES pages(id); ALTER TABLE ONLY wikitext ADD CONSTRAINT wikitext_page_id_fkey FOREIGN KEY (page_id) REFERENCES pages(id); " in ignore (guarded_exec ~conn sql); ignore (Database_upgrade.upgrade_schema ~conn) nurpawiki-1.2.3/database.mli0000644000175000017500000000640211133415525016541 0ustar jhellstenjhellsten(* Copyright (c) 2006-2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) type connection val with_conn : (connection -> 'a) -> 'a Lwt.t val guarded_exec : conn:connection -> string -> Postgresql.result val insert_save_page_activity : conn:connection -> user_id:int -> int -> unit val query_todos_by_ids : conn:connection -> int list -> Types.todo list val query_todo : conn:connection -> int -> Types.todo option val todo_exists : conn:connection -> int -> bool val update_todo_activation_date : conn:connection -> int -> string -> unit val update_todo_descr : conn:connection -> int -> string -> unit val update_todo_owner_id : conn:connection -> int -> int option -> unit val query_all_active_todos : conn:connection -> current_user_id:int option -> unit -> Types.todo list val query_upcoming_todos : conn:connection -> current_user_id:int option -> int option * int option -> Types.todo list val new_todo : conn:connection -> int -> int -> string -> string val todos_in_pages : conn:connection -> int list -> Types.page list Types.IMap.t val query_activity_in_pages : conn:connection -> min_id:int -> max_id:int -> Types.page list Types.IMap.t val query_highest_activity_id : conn:connection -> int val query_page_todos : conn:connection -> int -> Types.todo Types.IMap.t val update_page_todos : conn:connection -> int -> int list -> unit val complete_task : conn:connection -> user_id:int -> Types.IMap.key -> unit val uncomplete_task : conn:connection -> user_id:int -> Types.IMap.key -> unit val up_task_priority : int -> conn:connection -> unit val down_task_priority : int -> conn:connection -> unit val new_wiki_page : conn:connection -> user_id:int -> string -> int val save_wiki_page : conn:connection -> int -> user_id:int -> string list -> unit val find_page_id : conn:connection -> string -> int option val page_id_of_page_name : conn:connection -> string -> int val wiki_page_exists : conn:connection -> string -> bool val load_wiki_page : conn:connection -> ?revision_id:int option -> int -> string val query_page_revisions : conn:connection -> string -> Types.page_revision list val query_past_activity : conn:connection -> min_id:int -> max_id:int -> Types.activity list val search_wikipage : conn:connection -> string -> Types.search_result list val query_users : conn:connection -> Types.user list val query_user : conn:connection -> string -> Types.user option val add_user : conn:connection -> login:string -> passwd:string -> real_name:string -> email:string -> unit val update_user : conn:connection -> user_id:int -> passwd:string option -> real_name:string -> email:string -> unit val nurpawiki_schema_version : int nurpawiki-1.2.3/Makefile0000644000175000017500000000232511133415460015730 0ustar jhellstenjhellstenLIB := -package threads,netstring,calendar,extlib,postgresql,ocsigen CAMLC := ocamlfind ocamlc -thread -g $(LIB) CAMLOPT := ocamlfind ocamlopt -thread $(LIB) CAMLDOC := ocamlfind ocamldoc $(LIB) CAMLDEP := ocamlfind ocamldep CAMLBUILDOPTS := -ocamlc '$(CAMLC)' -ocamlopt '$(CAMLOPT)' CAMLBUILD := ocamlbuild $(CAMLBUILDOPTS) CMA := nurpawiki.cma CMXA := nurpawiki.cmxa CMXS := nurpawiki.cmxs TARGETS := $(CMA) ifneq ($(shell which ocamlopt),) TARGETS += $(CMXA) ifneq ($(wildcard $(shell ocamlc -where)/dynlink.cmxa),) TARGETS += $(CMXS) endif endif all: $(TARGETS) META $(CMA): version.ml $(CAMLBUILD) -classic-display -ocamlc '$(CAMLC)' $@ $(CMXA): version.ml $(CAMLBUILD) -classic-display -ocamlopt '$(CAMLOPT)' $@ %.cmxs: %.cmxa $(CAMLOPT) -shared -linkall -o _build/$@ _build/$< .PHONY: $(CMA) doc install NWIKI_VER=$(shell cat VERSION) version.ml:version.ml.in VERSION echo $(NWIKI_VER) sed -e "s|%_NURPAWIKI_VERSION_%|$(NWIKI_VER)|g" version.ml.in > version.ml META:META.in VERSION sed -e "s|%_NURPAWIKI_VERSION_%|$(NWIKI_VER)|g" META.in > META doc: # $(CAMLDOC) -d doc -html db.mli clean: -rm -Rf _build META version.ml install: ocamlfind install nurpawiki META $(foreach T,$(TARGETS),_build/$(T)) nurpawiki-1.2.3/main.ml0000644000175000017500000007153011251247564015563 0ustar jhellstenjhellsten(* Copyright (c) 2006-2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) open XHTML.M open Eliom_sessions open Eliom_parameters open Eliom_services open Eliom_predefmod.Xhtml open Lwt open ExtList open ExtString open Services open Types open Util module Db = Database module Psql = Postgresql module P = Printf (* TODO no need to extract here *) let matches_pcre rex s = try ignore (Pcre.extract ~rex s); true with Not_found -> false let (>>) f g = g f let newline_re = Pcre.regexp "\n" let task_side_effect_complete sp task_id () = Session.action_with_user_login sp (fun user -> Db.with_conn (fun conn -> if Privileges.can_complete_task ~conn task_id user then begin Db.complete_task ~conn ~user_id:user.user_id task_id; [Action_completed_task task_id] end else [])) let task_side_effect_undo_complete sp task_id () = Session.action_with_user_login sp (fun user -> Db.with_conn (fun conn -> if Privileges.can_complete_task ~conn task_id user then Db.uncomplete_task ~conn ~user_id:user.user_id task_id; [])) let task_side_effect_mod_priority sp (task_id, dir) () = Session.action_with_user_login sp (fun user -> Db.with_conn (fun conn -> if Privileges.can_modify_task_priority ~conn task_id user then begin if dir = false then Db.down_task_priority ~conn task_id else Db.up_task_priority ~conn task_id; [Action_task_priority_changed task_id] end else [])) let () = Eliom_predefmod.Actions.register ~service:task_side_effect_complete_action task_side_effect_complete; Eliom_predefmod.Actions.register ~service:task_side_effect_undo_complete_action task_side_effect_undo_complete; Eliom_predefmod.Actions.register ~service:task_side_effect_mod_priority_action task_side_effect_mod_priority let make_static_uri = Html_util.make_static_uri (* Deal with Wiki markup *) module WikiML = struct type preproc_line = [ `Wiki of string | `NoWiki of string list ] let ws_or_empty_re = Pcre.regexp "^([ \t\n\r]*)$" let h1_re = Pcre.regexp "^=(.*)=([ \n\r]*)?$" let h2_re = Pcre.regexp "^==(.*)==([ \n\r]*)?$" let h3_re = Pcre.regexp "^===(.*)===([ \n\r]*)?$" let list_re = Pcre.regexp "^[ ]?([*]+) (.*)([ \n\r]*)?$" let is_list = function `Wiki line -> match_pcre_option list_re line | `NoWiki _ -> None let is_list_or_empty = function `Wiki line -> matches_pcre list_re line || matches_pcre ws_or_empty_re line | `NoWiki _ -> false let take_while pred lines = let rec loop acc = function (x::xs) as lst -> if pred x then loop (x::acc) xs else (lst, List.rev acc) | [] -> ([], List.rev acc) in loop [] lines let accepted_chars_ = "a-zA-Z\128-\2550-9_!\"§°#%&/()=?+.,;:{}'@\\$\\^\\*`´<>~" let accepted_chars_sans_ws = "["^accepted_chars_^"-]+" let accepted_chars = "["^accepted_chars_^" -]+" let italic_re = Pcre.regexp ("^(_("^(del_substring accepted_chars "_")^")_)") let bold_re = Pcre.regexp ("^(\\*("^del_substring accepted_chars "\\*" ^")\\*)") let code_re = Pcre.regexp ("^(`("^del_substring accepted_chars "`" ^")`)") let text_re = Pcre.regexp ("^("^accepted_chars_sans_ws^")") let wikilink_re = Pcre.regexp "^([!]?[A-Z][a-z]+([A-Z][a-z]+)+)" let wikilinkanum_re = Pcre.regexp ("^(\\[(wiki|file|http|https|ftp):("^accepted_chars_sans_ws^ ")[ ]+("^accepted_chars^")\\])") let wikilinkanum_no_text_re = Pcre.regexp ("^(\\[(wiki|file|http|https|ftp):("^accepted_chars_sans_ws^")\\])") let todo_re = Pcre.regexp ("\\[todo:([0-9]+)( "^accepted_chars^")?\\]") let open_pre_re = Pcre.regexp "^(
|8<)\\s*$"
    let close_pre_re = Pcre.regexp "^(
|8<)\\s*$" (* WikiML preprocessor: translate a list of lines into normal lines and blocks of PRE blocks that contain verbatim lines. *) let preprocess lines = let rec loop acc = function x::xs -> (match match_pcre_option open_pre_re x with Some m -> begin (* Handle
..
*) let (after_pre,contents) = take_while (fun x -> match_pcre_option close_pre_re x = None) xs in let next = match after_pre with [] -> [] | _::next -> next in loop (`NoWiki contents :: acc) next end | None -> loop (`Wiki x::acc) xs) | [] -> List.rev acc in loop [] lines let wikitext_of_preprocessed_lines preproc_lines = List.flatten (List.map (function `Wiki text -> [text] | `NoWiki lines -> ("
" :: lines) @ ["
"]) preproc_lines) (* Todo item manipulation HTML *) let complete_todo sp id = [Html_util.complete_task_img_link sp id] let priority_arrow sp ~conn id up_or_down = let (title,arrow_img,dir) = if up_or_down then ("Raise priority!", "arrow_up.png", true) else ("Lower priority!", "arrow_down.png", false) in let arrow_img = img ~alt:"Logo" ~src:(make_static_uri sp [arrow_img]) () in Eliom_predefmod.Xhtml.a ~a:[a_title title] ~service:task_side_effect_mod_priority_action ~sp [arrow_img] (id,dir) let mod_priorities sp ~conn pri id = [priority_arrow sp ~conn id true; priority_arrow sp ~conn id false] let todo_editor_link sp todo_id page = Html_util.todo_edit_img_link sp (ET_view page) todo_id let todo_modify_buttons sp ~conn ~cur_user page todo_id todo = let completed = todo.t_completed in span ~a:[a_class ["no_break"]] (if completed || not (Privileges.can_edit_task todo cur_user) then [] else (todo_editor_link sp todo_id page @ mod_priorities sp ~conn todo.t_priority todo_id @ complete_todo sp todo_id)) let translate_list items = let add_ul t lst = t @ [ul (List.hd lst) (List.tl lst)] in let rec loop = function ((nesting1,text1)::(nesting2,text2)::xs) as lst -> if nesting1 = nesting2 then (li text1)::loop (List.tl lst) else if nesting1 < nesting2 then (* enter *) let (next_same_level,same_or_higher) = take_while (fun (n,_) -> n >= nesting2) (List.tl lst) in (li (add_ul text1 (loop same_or_higher)))::loop next_same_level else (* leave *) loop (List.tl lst) | (nesting,text)::[] -> [(li text)] | [] -> [] in let list_items = loop items in ul (List.hd list_items) (List.tl list_items) let parse_lines sp ~conn ~cur_user cur_page (todo_data : todo IMap.t) preprocessed_lines = let wikilink ~conn scheme page text = let ext_img = img ~alt:"External link" ~src:(make_static_uri sp ["external_link.png"]) () in if scheme = "wiki" || scheme = "" then let t = if text = "" then page else text in if Db.wiki_page_exists ~conn page then a wiki_view_page sp [pcdata t] (page,(None,(None,None))) else a ~a:[a_class ["missing_page"]] ~service:wiki_view_page ~sp:sp [pcdata t] (page,(None,(None,None))) else (* External link *) let url = scheme^":"^page in let t = if text = "" then url else text in XHTML.M.a ~a:[a_href (uri_of_string url)] [pcdata t] in let add_html html_acc html = html::html_acc in let add_todo acc todo = let todo_id = int_of_string todo in let html = try let todo = IMap.find todo_id todo_data in let completed = todo.t_completed in let style = if completed then ["todo_descr_completed"] else ["todo_descr"; Html_util.priority_css_class todo.t_priority] in span [todo_modify_buttons sp ~conn ~cur_user cur_page todo_id todo; span ~a:[a_class style] (Html_util.todo_descr_html todo.t_descr todo.t_owner)] with Not_found -> (pcdata "UNKNOWN TODO ID!") in add_html acc html in let seqmatch s charpos ~default = let rec loop = function (x,f)::xs -> (match match_pcre_option ~charpos x s with Some m -> let fmlen = String.length m.(0) in f fmlen m | None -> loop xs) | [] -> default () in loop in let rec parse_text acc s = let wiki_error s charpos = let s = (String.sub s charpos ((String.length s)-charpos)) in add_html acc (Html_util.error ("WIKI SYNTAX ERROR on line: '"^s^"'")) in let len = String.length s in let rec loop acc charpos = if charpos >= len then acc else if s.[charpos] = '\t' then let m = "\t" in loop (add_html acc (pcdata m)) (charpos+1) else if s.[charpos] = ' ' then let m = " " in loop (add_html acc (pcdata m)) (charpos+1) else if s.[charpos] = '\r' || s.[charpos] = '\n' then acc else seqmatch s charpos ~default:(fun () -> wiki_error s charpos) [(todo_re, (fun fmlen r -> let todo_id = r.(1) in loop (add_todo acc todo_id) (charpos+fmlen))); (wikilink_re, (fun fmlen r -> let m = r.(1) in (* If the WikiLink starts with a bang (!), don't create a link but leave it as text. *) if m.[0] = '!' then let s = String.sub m 1 (String.length m - 1) in loop (add_html acc (pcdata s)) (charpos+(String.length m)) else loop (add_html acc (wikilink ~conn "" m m)) (charpos+fmlen))); (wikilinkanum_re, (fun fmlen r -> let scheme = r.(2) in let page = r.(3) in let text = r.(4) in loop (add_html acc (wikilink ~conn scheme page text)) (charpos+fmlen))); (wikilinkanum_no_text_re, (fun fmlen r -> let scheme = r.(2) in let page = r.(3) in let text = "" in loop (add_html acc (wikilink ~conn scheme page text)) (charpos+fmlen))); (italic_re, (fun fmlen r -> let h = em [pcdata r.(2)] in loop (add_html acc h) (charpos+fmlen))); (bold_re, (fun fmlen r -> let h = strong [pcdata r.(2)] in loop (add_html acc h) (charpos+fmlen))); (code_re, (fun fmlen r -> let h = code [pcdata r.(2)] in loop (add_html acc h) (charpos+fmlen))); (text_re, (fun fmlen r -> loop (add_html acc (pcdata r.(1))) (charpos+fmlen)))] in List.rev (loop acc 0) in let rec pcre_first_match str pos = let rec loop = function (rex,f)::xs -> (try Some (Pcre.extract ~rex ~pos str, f) with Not_found -> loop xs) | [] -> None in loop in let rec loop acc = function ((`Wiki x)::xs) as lst -> let parse_list r = (* Grab all lines starting with '*': *) let (after_bullets,bullets) = take_while is_list_or_empty lst in let list_items = List.filter_map (function (`Wiki e) as wl -> if matches_pcre ws_or_empty_re e then (* Empty line, ignore *) None else begin match is_list wl with Some r -> let n_stars = String.length r.(1) in Some (n_stars, parse_text [] r.(2)) | None -> assert false end | `NoWiki _ -> assert false) bullets in loop ((translate_list list_items)::acc) after_bullets in let wiki_pats = [(h3_re, (fun r -> loop ((h3 [pcdata r.(1)])::acc) xs)); (h2_re, (fun r -> loop ((h2 [pcdata r.(1)])::acc) xs)); (h1_re, (fun r -> loop ((h1 [pcdata r.(1)])::acc) xs)); (ws_or_empty_re, (fun r -> loop acc xs)); (list_re, (fun r -> parse_list r))] in begin match pcre_first_match x 0 wiki_pats with Some (res, action) -> action res | None -> loop ((p (parse_text [] x))::acc) xs end | (`NoWiki x::xs) -> loop (pre [pcdata (String.concat "\n" x)]::acc) xs | [] -> List.rev acc in loop [] preprocessed_lines end let load_wiki_page ~conn ~revision_id page_id = Db.load_wiki_page ~conn~revision_id page_id >> Pcre.split ~rex:newline_re >> WikiML.preprocess let wikiml_to_html sp ~conn ~cur_user (page_id:int) (page_name:string) ~revision_id todo_data = load_wiki_page ~conn page_id ~revision_id >> WikiML.parse_lines sp ~conn ~cur_user page_name todo_data let todo_list_table_html sp ~conn ~cur_user cur_page todos = (* Which pages contain TODOs, mapping from todo_id -> {pages} *) let todo_in_pages = Db.todos_in_pages ~conn (List.map (fun todo -> todo.t_id) todos) in let todo_page_link todo = let descr = todo.t_descr in let page_links = let c = "wiki_pri_"^Html_util.string_of_priority todo.t_priority in Html_util.todo_page_links sp todo_in_pages ~link_css_class:(Some c) (todo.t_id) in Html_util.todo_descr_html descr todo.t_owner @ page_links in let priority_changes = Session.any_task_priority_changes sp in table ~a:[a_class ["todo_table"]] (tr (th [pcdata "Id"]) [th [pcdata "Description"]]) (List.map (fun todo -> let id = todo.t_id in let completed = todo.t_completed in let row_pri_style = if completed then "todo_completed_row" else Html_util.priority_css_class todo.t_priority in let row_class = row_pri_style:: (if List.mem id priority_changes then ["todo_priority_changed"] else []) in (tr (td ~a:[a_class row_class] [pcdata (string_of_int id)]) [td ~a:[a_class row_class] (todo_page_link todo); td [(WikiML.todo_modify_buttons sp ~conn ~cur_user cur_page id todo)]])) todos) let wiki_page_menu_html sp ~conn ~cur_user page content = let edit_link = [a ~service:wiki_edit_page ~sp:sp ~a:[a_accesskey '1'; a_class ["ak"]] [img ~alt:"Edit" ~src:(make_static_uri sp ["edit.png"]) (); pcdata "Edit page"] page] in let printable_link = [a ~service:wiki_view_page ~sp:sp ~a:[a_accesskey 'p'; a_class ["ak"]] [pcdata "Print"] (page, (Some true,(None,None)))] in let revisions_link = [a ~sp ~service:page_revisions_page [pcdata "View past versions"] page; br (); br ()] in let current_user_id = Some cur_user.user_id in let todo_list = todo_list_table_html sp ~conn ~cur_user page (Db.query_all_active_todos ~conn ~current_user_id ()) in let undo_task_id = Session.any_complete_undos sp in let top_info_bar = match undo_task_id with None -> [] | Some id -> [span ~a:[a_class ["action_bar"]] [pcdata ("Completed task "^string_of_int id^" "); a ~a:[a_class ["undo_link"]] ~service:task_side_effect_undo_complete_action ~sp [pcdata "Undo"] id]] in Html_util.navbar_html sp ~cur_user ~wiki_page_links:(edit_link @ [pcdata " "] @ printable_link) ~wiki_revisions_link:revisions_link ~top_info_bar ~todo_list_table:[todo_list] content let wiki_page_contents_html sp ~conn ~cur_user ~revision_id page_id page_name todo_data ?(content=[]) () = wiki_page_menu_html sp ~conn ~cur_user page_name (content @ wikiml_to_html sp ~conn ~cur_user ~revision_id page_id page_name todo_data) let view_page sp ~conn ~cur_user ?(revision_id=None) page_id page_name ~printable = let todos = Db.query_page_todos ~conn page_id in if printable <> None && Option.get printable = true then let page_content = wikiml_to_html sp ~conn ~cur_user page_id page_name ~revision_id todos in Html_util.html_stub sp page_content else Html_util.html_stub sp (wiki_page_contents_html sp ~conn ~cur_user page_id page_name ~revision_id todos ()) (* Parse existing todo's from the current to-be-saved wiki page and update the DB relation on what todos are on the page. Todo descriptions are inspected and if they've been changed, modify them in the DB. It's also possible to resurrect completed tasks here by removing the '(x)' part from a task description. *) let check_new_and_removed_todos ~conn ~cur_user page_id lines = let search_forward ?groups pat s pos = let result = Pcre.exec ~rex:pat ~pos s in (fst (Pcre.get_substring_ofs result 0), result) in (* Figure out which TODOs are mentioned on the wiki page: *) let page_todos = List.fold_left (fun acc -> function `Wiki line -> let rec loop acc n = try let (offs,res) = search_forward WikiML.todo_re line n in let m = try Some (Pcre.get_substring res 2) with Not_found -> None in loop ((Pcre.get_substring res 1, m)::acc) (offs+(String.length (Pcre.get_substring res 0))) with Not_found -> acc in loop acc 0 | `NoWiki _ -> acc) [] lines in (* Query todos that reside on this page. Don't update DB for todos that did NOT change *) let todos_on_page = Db.query_page_todos ~conn page_id in let completed_re = Pcre.regexp "^\\s*\\(x\\) (.*)$" in let remove_ws_re = Pcre.regexp "^\\s*(.*)$" in (* Update todo descriptions & resurrect completed tasks *) List.iter (fun (id_s,descr) -> match descr with Some descr -> (match match_pcre_option completed_re descr with Some _ -> (* Task has already been completed, do nothing: *) () | None -> let id = int_of_string id_s in (* Update task description (if not empty): *) (match match_pcre_option remove_ws_re descr with Some r -> begin try let new_descr = r.(1) in (* Only modify task description in DB if it's changed from its previous value: *) let todo = IMap.find id todos_on_page in (* Resurrect completed task *) if todo.t_completed then Db.uncomplete_task ~conn ~user_id:cur_user.user_id id; if todo.t_descr <> new_descr then Db.update_todo_descr ~conn id new_descr with Not_found -> (* Internal inconsistency, should not happen. *) () end | None -> ())) | None -> ()) page_todos; List.filter_map (fun e -> let id = int_of_string (fst e) in if Db.todo_exists ~conn id then Some id else None) page_todos >> (* Update DB "todos in pages" relation *) Db.update_page_todos ~conn page_id let global_substitute ?groups pat subst s = Pcre.substitute_substrings ~rex:pat ~subst:(fun r -> subst r) s let new_todo_re = Pcre.regexp ("\\[todo ("^WikiML.accepted_chars^")\\]") (* Insert new TODOs from the wiki ML into DB and replace [todo descr] by [todo:ID] *) let convert_new_todo_items ~conn cur_user page = let owner_id = cur_user.user_id in List.map (function `Wiki line -> `Wiki (global_substitute new_todo_re (fun r -> let descr = Pcre.get_substring r 1 in let id = Db.new_todo ~conn page owner_id descr in "[todo:"^id^" "^descr^"]") line) | (`NoWiki _) as x -> x) (* Save page as a result of /edit?p=Page *) let service_save_page_post = register_new_post_service ~fallback:wiki_view_page ~post_params:(string "value") (fun sp (page,_) value -> Session.with_user_login sp (fun cur_user sp -> (* Check if there are any new or removed [todo:#id] tags and updated DB page mappings accordingly: *) let wikitext = Pcre.split ~rex:newline_re value >> WikiML.preprocess in let user_id = cur_user.user_id in Db.with_conn (fun conn -> let page_id = Db.page_id_of_page_name ~conn page in check_new_and_removed_todos ~conn ~cur_user page_id wikitext; (* Convert [todo Description] items into [todo:ID] format, save descriptions to database and save the wiki page contents. *) let wiki_plaintext = convert_new_todo_items ~conn cur_user page_id wikitext >> WikiML.wikitext_of_preprocessed_lines in (* Log activity: *) Db.insert_save_page_activity ~conn ~user_id page_id; Db.save_wiki_page page_id ~conn ~user_id wiki_plaintext; view_page sp ~conn ~cur_user page_id page ~printable:(Some false)))) (* Convert [todo:ID] into [todo:ID 'Description'] before going into Wiki page edit textarea. *) let annotate_old_todo_items page page_todos (lines : WikiML.preproc_line list) = List.map (function `Wiki line -> `Wiki (global_substitute WikiML.todo_re (fun r -> let id = Pcre.get_substring r 1 in let (descr,completed) = try let todo = IMap.find (int_of_string id) page_todos in (todo.t_descr,if todo.t_completed then "(x) " else "") with Not_found -> ("UNKNOWN TODO","") in "[todo:"^id^" "^completed^descr^"]") line) | (`NoWiki line) as x -> x) lines (* /edit?p=Page *) let _ = let handle_edit ~conn ~cur_user sp page_name = let (page_id,page_todos,preproc_wikitext) = if Db.wiki_page_exists ~conn page_name then let page_id = Db.page_id_of_page_name ~conn page_name in let current_page_todos = Db.query_page_todos ~conn page_id in (page_id, current_page_todos, load_wiki_page ~conn page_id ~revision_id:None >> annotate_old_todo_items page_name current_page_todos) else begin (Db.new_wiki_page ~conn ~user_id:cur_user.user_id page_name, IMap.empty, []) end in let wikitext = String.concat "\n" (WikiML.wikitext_of_preprocessed_lines preproc_wikitext) in let f = post_form service_save_page_post sp (fun chain -> [(p [string_input ~input_type:`Submit ~value:"Save" (); Html_util.cancel_link wiki_view_page sp (page_name,(None,(None,None))); br (); textarea ~name:chain ~rows:30 ~cols:80 ~value:(pcdata wikitext) ()])]) (page_name,(None,(None,None))) in Html_util.html_stub sp (wiki_page_contents_html sp ~conn ~cur_user ~revision_id:None page_id page_name page_todos ~content:[f] ()) in register wiki_edit_page (fun sp page_name () -> Session.with_user_login sp (fun cur_user sp -> Db.with_conn (fun conn -> handle_edit ~conn ~cur_user sp page_name))) let view_wiki_page sp ~conn ~cur_user (page_name,(printable,(revision_id,_))) = match Db.find_page_id ~conn page_name with Some page_id -> view_page sp ~conn ~cur_user ~revision_id page_id page_name ~printable | None -> let f = a wiki_edit_page sp [pcdata "Create new page"] page_name in Html_util.html_stub sp (wiki_page_menu_html sp ~conn ~cur_user page_name [f]) (* /view?p=Page *) let _ = register wiki_view_page (fun sp ((_,(_,(_,force_login))) as params) () -> (* If forced login is not requested, we'll let read-only guests in (if current configuration allows it) *) let login = match force_login with Some true -> Session.with_user_login sp | Some _ | None -> Session.with_guest_login sp in login (fun cur_user sp -> Db.with_conn (fun conn -> view_wiki_page sp ~conn ~cur_user params))) (* /benchmark?test=empty,one_db *) let _ = let gen_html sp = function "empty" -> (html (head (title (pcdata "")) []) (body [p [pcdata "Empty page"]])) | "db1" -> (* TODO TODO add simple SQL query here *) (* ignore (Db.query_activities ());*) (html (head (title (pcdata "")) []) (body [p [pcdata "Test one DB query"]])) | _ -> (html (head (title (pcdata "")) []) (body [p [pcdata "invalid 'test' param!"]])) in register benchmark_page (fun sp test_id () -> return (gen_html sp test_id)) (* /search?q=[keyword list] *) let _ = (* Parse tags from headline and convert to b tags. *) let html_of_headline h = let rec html_of_elem = function Nethtml.Element ("b",_,c) -> let c = List.flatten (List.rev (List.fold_left (fun acc e -> (html_of_elem e)::acc) [] c)) in [(span ~a:[a_class ["sr_hilite"]] c)] | Nethtml.Element (_,_,_) -> [] | Nethtml.Data s -> [pcdata s] in let ch = new Netchannels.input_string h in let doc = Nethtml.parse ch in List.flatten (List.rev (List.fold_left (fun acc e -> (html_of_elem e)::acc) [] doc) )in let render_results sp search_results = List.flatten (List.map (fun sr -> match sr.sr_result_type with SR_page -> let link descr = a ~a:[a_class ["sr_link"]] ~service:wiki_view_page ~sp:sp [pcdata descr] (descr,(None,(None,None))) in [p ([link (Option.get sr.sr_page_descr); br ()] @ html_of_headline sr.sr_headline)] | SR_todo -> assert false) search_results) in let gen_search_page sp ~cur_user search_str = Db.with_conn (fun conn -> Db.search_wikipage ~conn search_str) >>= fun search_results -> return (Html_util.html_stub sp (Html_util.navbar_html sp ~cur_user ([h1 [pcdata "Search results"]] @ (render_results sp search_results)))) in register search_page (fun sp search_str () -> Session.with_guest_login sp (fun cur_user sp -> gen_search_page sp cur_user search_str)) nurpawiki-1.2.3/scheduler.ml0000644000175000017500000002765311133415460016613 0ustar jhellstenjhellsten(* Copyright (c) 2006-2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) open XHTML.M open Eliom_sessions open Eliom_parameters open Eliom_services open Eliom_predefmod.Xhtml open Lwt open ExtList open ExtString open Services open Types open Util open CalendarLib module Db = Database let clamp_date_to_today date = let today = Date.today () in let d = date_of_string date in begin match Date.compare today d with -1 -> d | 0 | 1 -> today | _ -> assert false end let wiki_page_links sp todo_in_pages todo = let id = todo.t_id in let c = "wiki_pri_"^Html_util.string_of_priority todo.t_priority in Html_util.todo_page_links sp todo_in_pages ~link_css_class:(Some c) id let view_scheduler_page sp ~conn ~cur_user = let scheduler_page_internal sp ~conn ~cur_user = let today = Date.today () in let prettify_activation_date d = let d = date_of_string d in (* Clamp & prettify activation date *) begin match Date.compare today d with -1 -> Printer.DatePrinter.sprint "%a %b %d, %Y" d | 0 | 1 -> "today" | _ -> assert false end in let todo_table_html sp todos todos_in_pages = let prev_heading = ref "" in let todo_rows = List.map (fun (heading,todo) -> let todo_id_s = string_of_int todo.t_id in let heading_row = if !prev_heading <> heading then begin prev_heading := heading; [tr (td ~a:[a_class ["rm_table_heading"]] [pcdata heading]) []] end else [] in let pri_style = Html_util.priority_css_class todo.t_priority in let todo_row = tr (td ~a:[a_class ["rm_edit"]] (Html_util.todo_edit_img_link sp ET_scheduler todo.t_id)) [td [raw_checkbox ~name:("t-"^ todo_id_s) ~value:"0" ()]; td [Html_util.complete_task_img_link sp todo.t_id]; (td ~a:[a_class ["no_break"; pri_style]] [pcdata (prettify_activation_date todo.t_activation_date)]); td ~a:[a_class [pri_style]] (Html_util.todo_descr_html todo.t_descr todo.t_owner @ wiki_page_links sp todos_in_pages todo)] in heading_row @ [todo_row]) todos in List.flatten todo_rows in let todo_section sp todos todos_in_pages = (todo_table_html sp todos todos_in_pages) in let query_todos = if Privileges.can_schedule_all_tasks cur_user || cur_user.user_login = "guest" then Database.query_upcoming_todos ~conn ~current_user_id:None else (* Query this users's tasks only: *) Database.query_upcoming_todos ~conn ~current_user_id:(Some cur_user.user_id) in let upcoming_pending = query_todos (None,None) in let upcoming_tomorrow = query_todos (None,Some 1) in let upcoming_todos_7_days = query_todos (Some 1,Some 7) in let upcoming_todos_14_days = query_todos (Some 7, Some 14) in let upcoming_all = query_todos (Some 14, None) in let mark_todo_hdr h = List.map (fun e -> (h, e)) in let merged_todos = (mark_todo_hdr "Today" upcoming_pending) @ (mark_todo_hdr "Tomorrow" upcoming_tomorrow) @ (mark_todo_hdr "Next 7 days" upcoming_todos_7_days) @ (mark_todo_hdr "Next 2 weeks" upcoming_todos_14_days) @ (mark_todo_hdr "Everything else" upcoming_all) in let todos_in_pages = Database.todos_in_pages ~conn (List.map (fun (_,todo) -> todo.t_id) merged_todos) in (* TODO merge this HTML generation with other pages. PROBLEM: don't know how to easily do that without duplicating the parameter passing of pages. *) let table () = [p [raw_input ~input_type:`Submit ~value:"Mass edit" ()]; table (tr (th []) [th []; th []; th [pcdata "Activates on"]; th [pcdata "Todo"]]) (todo_section sp merged_todos todos_in_pages); table (tr (td [button ~a:[a_class ["scheduler_check_button"]; a_id "button_select_all"] ~button_type:`Button [pcdata "Select All"]]) [td [button ~a:[a_class ["scheduler_check_button"]; a_id "button_deselect_all"] ~button_type:`Button [pcdata "Unselect All"]]]) []] in let table' = post_form edit_todo_page sp table (ET_scheduler, None) in Html_util.html_stub sp ~javascript:[["nurpawiki_scheduler.js"]] (Html_util.navbar_html sp ~cur_user ([h1 [pcdata "Road ahead"]] @ [table'])) in scheduler_page_internal sp ~conn ~cur_user let render_edit_todo_cont_page sp ~conn ~cur_user = function ET_scheduler -> view_scheduler_page sp ~conn ~cur_user | ET_view wiki_page -> Main.view_wiki_page sp ~conn ~cur_user (wiki_page,(None,(None,None))) (* /scheduler *) let _ = register scheduler_page (fun sp todo_id () -> Session.with_guest_login sp (fun cur_user sp -> Db.with_conn (fun conn -> view_scheduler_page sp ~conn ~cur_user))) let scheduler_page_discard_todo_id = register_new_service ~path:["scheduler"] ~get_params:((Eliom_parameters.user_type et_cont_of_string string_of_et_cont "src_service")) (fun sp (src_page_cont) () -> Session.with_user_login sp (fun cur_user sp -> Db.with_conn (fun conn -> render_edit_todo_cont_page sp ~conn ~cur_user src_page_cont))) (* Save page as a result of /edit_todo?todo_id=ID *) let service_save_todo_item = register_new_post_service ~fallback:scheduler_page_discard_todo_id ~post_params:(list "todos" ((int "todo_id") ** (string "activation_date") ** (string "descr") ** (string "owner_id"))) (fun sp src_page_cont todos -> Session.with_user_login sp (fun cur_user sp -> Db.with_conn (fun conn -> (* TODO security hole: would need to check user privileges for these DB operations. *) List.iter (fun (todo_id,(activation_date,(descr,owner_id))) -> Database.update_todo_descr ~conn todo_id descr; let owner_id_opt = if owner_id = "" then None else Some (int_of_string owner_id) in Database.update_todo_owner_id ~conn todo_id owner_id_opt; Database.update_todo_activation_date ~conn todo_id activation_date) todos; render_edit_todo_cont_page sp ~conn ~cur_user src_page_cont))) let rec render_todo_editor sp ~conn ~cur_user (src_page_cont, todos_to_edit) = let users = Database.query_users ~conn in let todos_str = String.concat "," (List.map string_of_int todos_to_edit) in let todos = Database.query_todos_by_ids ~conn todos_to_edit in let f = let todo_in_pages = Database.todos_in_pages ~conn (List.map (fun todo -> todo.t_id) todos) in let cancel_page cont = match cont with ET_scheduler -> Html_util.cancel_link scheduler_page sp () | ET_view wiki -> Html_util.cancel_link wiki_view_page sp (wiki,(None,(None,None))) in let owner_selection chain todo = let match_owner u = function Some o -> o.owner_id = u.user_id | None -> false in let options = List.map (fun u -> Option ([], string_of_int u.user_id, Some (pcdata u.user_login), match_owner u todo.t_owner)) users in string_select ~name:chain (Option ([], "", None, false)) options in let todo_descr chain v = string_input ~input_type:`Text ~name:chain ~value:v () in (* See nurpawiki_calendar.js for JavaScript calendar binding details. *) let create_listform f = [table (tr (th [pcdata "ID"]) [th [pcdata "Description"]; th [pcdata "Activates on"]]) (f.it (fun (tv_id,(tv_act_date,(tv_descr,tv_owner_id))) todo -> let pri_style = Html_util.priority_css_class todo.t_priority in [tr ~a:[a_class [pri_style]] (td [pcdata (string_of_int todo.t_id)]) [td (todo_descr tv_descr todo.t_descr :: wiki_page_links sp todo_in_pages todo); td ~a:[a_class ["no_break"]] [string_input ~a:[a_readonly `Readonly; a_id ("calendar_"^(string_of_int todo.t_id))] ~input_type:`Text ~name:tv_act_date ~value:todo.t_activation_date (); button ~a:[a_id ("cal_button_"^(string_of_int todo.t_id))] ~button_type:`Button [pcdata "..."]]; td [owner_selection tv_owner_id todo; int_input ~name:tv_id ~input_type:`Hidden ~value:todo.t_id ()]]]) todos [tr (td [string_input ~input_type:`Submit ~value:"Save" (); cancel_page src_page_cont]) []])] in post_form ~service:service_save_todo_item ~sp create_listform src_page_cont in let heading = [pcdata ("Edit TODOs "^todos_str)] in let help_str = pcdata "NOTE: Below activation date will be assigned for all the items" in let calendar_js = [["jscalendar"; "calendar.js"]; ["jscalendar"; "lang"; "calendar-en.js"]; ["jscalendar"; "calendar-setup.js"]; ["nurpawiki_calendar.js"]] in Html_util.html_stub sp ~javascript:calendar_js (Html_util.navbar_html sp ~cur_user ((h1 heading)::[help_str; br(); f])) let error_page sp msg = Html_util.html_stub sp [h1 [pcdata ("ERROR: "^msg)]] let render_todo_get_page sp ~conn ~cur_user (src_page_cont, todo) = match todo with Some todo_id -> render_todo_editor sp ~conn ~cur_user (src_page_cont, [todo_id]) | None -> (* Bogus input as we didn't get any todos to edit.. But let's just take the user back to where he came from rather than issueing an error message. *) render_edit_todo_cont_page sp ~conn ~cur_user src_page_cont let _ = register edit_todo_get_page (fun sp get_params () -> Session.with_user_login sp (fun cur_user sp -> Db.with_conn (fun conn -> render_todo_get_page sp ~conn ~cur_user get_params))) let todo_id_re = Pcre.regexp "^t-([0-9]+)$" let parse_todo_ids todo_ids = try List.map (fun (todo_id_str,b) -> match match_pcre_option todo_id_re todo_id_str with Some r -> int_of_string r.(1) | None -> raise Not_found) todo_ids with Not_found -> [] let _ = register edit_todo_page (fun sp (src_page_cont, single_tid) (todo_ids : (string * string) list) -> Session.with_user_login sp (fun cur_user sp -> Db.with_conn (fun conn -> if todo_ids = [] then render_todo_get_page sp ~conn ~cur_user (src_page_cont, single_tid) else render_todo_editor sp ~conn ~cur_user (src_page_cont, (parse_todo_ids todo_ids))))) nurpawiki-1.2.3/config.ml0000644000175000017500000000555011133415541016072 0ustar jhellstenjhellsten(* Copyright (c) 2007-2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) module P = Printf open Eliom_sessions open Simplexmlparser type db_config = { db_name : string; db_user : string; db_host : string option; db_port : string option; db_pass : string option; } type site_config = { cfg_allow_ro_guests : bool; cfg_homepage : string; } let get_attr_opt attr attrs = try Some (List.assoc attr attrs) with Not_found -> None let get_attr_with_err e attr attrs = try (List.assoc attr attrs) with Not_found -> raise (Ocsigen_extensions.Error_in_config_file ("Expecting "^e^"."^attr^" attribute in Nurpawiki config")) let dbcfg = let rec find_dbcfg = function (Element ("database", attrs, _)::_) -> let dbname = get_attr_with_err "database" "name" attrs in let dbuser = get_attr_with_err "database" "user" attrs in let dbhost = get_attr_opt "host" attrs in let dbport = get_attr_opt "port" attrs in let dbpass = get_attr_opt "password" attrs in { db_name = dbname; db_user = dbuser; db_host = dbhost; db_port = dbport; db_pass = dbpass; } | x::xs -> find_dbcfg xs | [] -> raise (Ocsigen_extensions.Error_in_config_file ("Couldn't find database element from config")) in find_dbcfg (get_config ()) let site = let rec find_site_cfg = function (Element ("nurpawiki", attrs, _))::_ -> let allow_ro_guests = (match get_attr_opt "allow_read_only_guests" attrs with Some s -> s = "yes" | None -> false) in let homepage = (match get_attr_opt "homepage" attrs with Some s -> s | None -> "WikiStart") in { cfg_allow_ro_guests = allow_ro_guests; cfg_homepage = homepage; } | (Element (x,_,_))::xs -> Ocsigen_messages.errlog x; find_site_cfg xs | _ -> { cfg_allow_ro_guests = false; cfg_homepage = "WikiStart"; } in let cfg = find_site_cfg (get_config ()) in Ocsigen_messages.warning (P.sprintf "read-only guests allowed %b" cfg.cfg_allow_ro_guests); cfg nurpawiki-1.2.3/COPYING0000644000175000017500000004310310724636613015334 0ustar jhellstenjhellsten GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. nurpawiki-1.2.3/gen_ocsigen_config0000755000175000017500000000553611154765605020046 0ustar jhellstenjhellsten#!/bin/sh #------------------------------------------------------------------ # Configure OCaml library paths based on information queried from # ocamlfind & command line and creates a configuration file for # Ocsigen. #------------------------------------------------------------------ set -e # Bail out on errors site_cma="_build/nurpawiki.cma" static_root="." if [ -z $1 ]; then true else if [ "$1" = "--godi-install" ]; then site_cma=`ocamlfind query nurpawiki`/nurpawiki.cma static_root="$LOCALBASE/share/nurpawiki" else echo Invalid args exit 1 fi fi stdlib_path=`ocamlfind ocamlc -where` str_path=`ocamlfind query str` nums_path="$stdlib_path" pcre_path=`ocamlfind query pcre` calendar_path=`ocamlfind query calendar` extlib_path=`ocamlfind query extlib` postgresql_path=`ocamlfind query postgresql` sqlite3_path=`ocamlfind query sqlite3` cryptokit_path=`ocamlfind query cryptokit` # The way we find Ocsigen METAS directory is extremely hacky. I don't # know of a better way. See issue 56 in # http://code.google.com/p/nurpawiki/issues/list for more info. ocsigen_metas_dir="`ocamlfind printconf stdlib`/../../ocsigen/METAS" if [ "$DEBUG" != "" ]; then echo $str_path echo $pcre_path echo $calendar_path echo $extlib_path echo $postgresql_path echo $sqlite3_path echo $ocsigen_metas_dir fi mkdir -p var/log mkdir -p var/run if [ "$DBNAME" = "" ]; then echo echo ERROR! echo echo DBNAME environment variable must be set to point to your nurpawiki DB echo exit 1 fi if [ "$DBUSER" = "" ]; then echo echo ERROR! echo echo DBUSER environment variable must be set to your nurpawiki DB username echo exit 1 fi if [ "$DBPASSWD" = "" ]; then echo echo ERROR! echo echo DBPASSWD environment variable must be set to your nurpawiki DB echo postgres user password. See DB installation instructions for echo more information on how to configure this. echo exit 1 fi cat ocsigen.conf.in | \ sed -e "s|%_OCSIGEN_ROOT_%|$OCSIGEN_ROOT|g" | \ sed -e "s|%_STR_CMA_%|${str_path}/str.cma|g" | \ sed -e "s|%_NUMS_CMA_%|${nums_path}/nums.cma|g" | \ sed -e "s|%_CALENDAR_CMA_%|${calendar_path}/calendarLib.cmo|g" | \ sed -e "s|%_PCRE_CMA_%|${pcre_path}/pcre.cma|g" | \ sed -e "s|%_EXTLIB_CMA_%|${extlib_path}/extLib.cma|g" | \ sed -e "s|%_POSTGRESQL_CMA_%|${postgresql_path}/postgresql.cma|g" | \ sed -e "s|%_CRYPTOKIT_CMA_%|${cryptokit_path}/cryptokit.cma|g" | \ sed -e "s|%_STATIC_ROOT_%|${static_root}|g" | \ sed -e "s|%_NURPAWIKI_CMA_%|${site_cma}|g" | \ sed -e "s|%_DBNAME_%|${DBNAME}|g" | \ sed -e "s|%_DBPASSWD_%|${DBPASSWD}|g" | \ sed -e "s|%_SQLITE3_CMA_%|${sqlite3_path}/sqlite3.cma|g" | \ sed -e "s|%_OCSIGEN_METAS_DIR_%|${ocsigen_metas_dir}|g" | \ sed -e "s|%_DBUSER_%|${DBUSER}|g" nurpawiki-1.2.3/files/0000755000175000017500000000000011251252514015370 5ustar jhellstenjhellstennurpawiki-1.2.3/files/mark_complete.png0000644000175000017500000000033010667075457020737 0ustar jhellstenjhellsten‰PNG  IHDR &ÎàqbKGDùC» pHYs  šœtIMEÖ ¨|^DeIDATxÚ¥Á À0M•¡’I¼[ÂVî#-©Z)Ÿò| ƒIÂ6޽lfmf™ù•ÇZÕ½÷×4’TVtÇ,IJºº$ zÊ‹ˆˆ‚¦o¢6Íé"–ÓÌtwîþ<Íþ~ À -MaKòý—4IEND®B`‚nurpawiki-1.2.3/files/arrow_up.png0000644000175000017500000000667210667075457017772 0ustar jhellstenjhellsten‰PNG  IHDR &Îàq âiCCPICC Profilexœ­—y8Ô]Ç¿c_“}„ˆH²V–±d_²o5f#cÆJ EQIËÓ®’VÒÓª¢´kQJmH©h#Q„š÷Ôóö<ïû\ïrþºÏ¹îûÜç÷û|®ë\í¢r8‰XIí_׈Üаp€` @>n4v 3_ÀãðB<yZ<•0æPB)bÜh\ €3ß@L£ÅñÂ#@„”Dg&¢ï‘YtF  ÓSh,€¸ |g±Øt@v€I4—ÈV0 '9Ê °hDŸþ\ã '‡ÌŸkzË%O ´îçZ_Šõ)±ÓÌ)'@¸ÏïÓD7ßÖóùÃ{øüo{ÁàR"-•›6ö¿„;ÀßÍG¿yl@@H`@HXXXDBTXLR\LBZRLJBZ–(-##K”“%ÉN ɓ䕔”•UTUÕÔTÕ5444µÈšÚ:::ººõô&êëN62661™bjjj6Õ|ê4 ‹é––VV6¶¶¶vv3fΜ9k¦½½£““…âLqqqu=ÛÝÝÃÝÓËËËÇÛ××ÏÏ? `N``PPpHHHhhxxDDddTttô¼yTjL N§3qqññLfsþüD‹Åæp8É\.7…Ëã¥òÒÒ.L_¸hQFÆâÅK–dffeeg/]º,'7gyîŠyyùù+W®ZµzuAÁš5……k×®[·~ý† ¿ý¶qã¦M›7oÙ²uë¶mÛ·íØ±sç®]ÅÅ»w—”ìÙ³wï¾}û÷Ð;pààÁÒÒ²²C‡ÊËþý÷#GŽ=vìøñ'Nž¬¨8eqêÔéÓgÎTVVU={î\uõùó.\¼xÉþҥ˗¯\¹zµ¦æÚµë×oܸy³vvmí­[·o×Õݹs×ûîÝúú{÷îßoðohhl|ð ©©9¨¹ùáÃG?~öäÉÓ§--­­mQmmÏžµ·?þâEGLGÇË—¯^½~ÝÙÙ×ÕõæÍÛ·ïÞ½ÿáC7«»»§çãÇÞÞOŸú¸}}ýýŸ?ù2008øõëPúÐÐððÈÈ·oß¿ó3ùüQþ‚!!aq!Q 1Qq) QIq)i)"QFZVFN†$7AN~‚‚¢¢’’‚²ŠŠªªŠšººº†¦¦†™LÖÖÖÑÕÕÑÓÓ×7Пd`8ÉÈhòdcS33Ó©æææÓÌ-,¦O·²¶¶¶±±µ³³›a7s¦½ƒƒƒ££“#…âììââæ:ÛÍÝÃÃÃÓÃËËÇÇ×ÏÏßß? 0(((88$$44,,<"2"**:zîÜyT*•F£ÓŒØØ¸ØøxfBBB"‹ÅJb³Ùvr279%eÔ‚ ÒÓ± {Ù²œœÜÜåËÿg~Z`ô—ŒZ`õ'þh˘ãxݹó†ƀ1 þì@Û³gísÇ7 ¶³óŸ èîIúaÀ8ÿ´1~áOX&ÀtRê>'²R4Rlª¸¨x“D‰$WÊEZ^ºƒxJ&WÖ_NS®›T5!O>TÁ@¡Oñ¼Rž²¿ŠªJ»ê!µTu{ a[škµ‚ÈäíC:l]3݉Uz‹ôgè7¸:)×ÐÅHʨnòco1“Ú)ù¦.fBfצ.7§LS˜öÁâÊôÍ–‰VÖrÖ6§lóìÂfL™)6³eÖ û•ÑŽfNpj ”:/qqwÕpíq«™½Í}¾‡­§¬g›×ïÞY>^¾*¾oý*ýs|ç¨Íé <”ì"r?tKؼp£ðO§#F͈ˆ¾67žUŽz7f5Í›.Mod”ÆnŽ[¿š™‘:?1‘Ú—ÁváX'suR&ð„yƒ©i ªîO߸('ƒ½Øg‰UæÄ,©¬žìK«—çdæÆ/Ÿ½Â(O&ïS~ãÊŠU›W§D®±+Ô(ü¶¶eÝ…õ%ò~coôÝdº™´ypKÛÖ ÛvnÏ.ŠÛá¿Óv—f±`qÿîþ’¡=Ã{¿ìëßÿñ@ÏÁ®Òö²ŽC­å×ý^säÂÑÊc'=qøä¡Š²Se§ËÏ©¼^Uw¶ñÜ“êÎ „‹ —Ì.»_I¼º©æòµžZ7ýjóo5ÔéÞI»[wÏðþöFÒƒõÍú¯>ŽjÐ*ÐÖÕÞÝ¡ò*¶³ùíÚk{‰ŸYÚ|>0z÷€ˆ%°Å¾’€Uf€A9 X øI6Ðvƒ€Ü;\4Çï I(BVðKQŒËxE$L'P ë— Ÿ& ЊZÕç î|+d!”%tGXCØU˜#\#¢&©5-íÓ «'‹¯ÿ"A—h’t“\*Y-e.U.­/½‡¨M¤Kd&ʔɚÊVÊQäêIФ(R÷„lyùrŠÂ:…VÅt%%¥Óʡʇ”GTJTg«öªíPëSwWÔ(ՌВÑJкF^¢m¥ýI瘮Œ.{¢ÙÄ>½3ú™®å“d'µ–¥Oö0V7î5‰4¹1e·iºYÐÔiæ$ó¾iMnUÓw[æY%[GÚ¸ÛZÛMš¡:“8KpVÖ¬aû~‡nÇ·N]”.ç7.ï]{Ýfó=Ä=å½´½Í||übý36Ì)¼ô<˜ªfNXYÕ=ewËý„m?Î<ñé´ä™mU†gÏž~qÁe╃5Ž72jUn­‹¸Ã¿ïÑÐû ¨Ùåaïãâ~Ûñvú •Ž{Ž]#o«Þ§u[ö ôV}v¼7´}„ÁçÿàÿßÐÿ#ûHÑÑî_Ø%Ýþö­Š“°Q)Qée¯î®>¨á7Æ~œ¼¿Î±Ÿäõ_¸þ-ù1îV¯!ÿàN;ú+ù?r_õGòãÜóÿŽüÎþâ„=á{›öû²?ü`œ}EæiÉ*óg«½Gé×8^kýkúO}Zø£ô_åóïè­ê[ü @$èÂAHÅ6\F7L$n H ø  t Ú¾r*f ·Šx‰\µ=%f)V%î ~K"J¢[2_JOªFšA”!ž’aÈ*É6Ê­&yO™Ð ¿K!LQF±^i²¿ŠªÊ+Õ“j¹êA:Ú÷´ÊÉÚ\]›‰ÆzÊúúƒÝ“Þ¾0z3ùqß˜Š›iMµ4÷–`±~ú ËçÖr6޶»Òïf™Ø'9œsäSœOºŠ»ÅÍ®poòøà9ä­îcáëïGõ_P:§5H$xjHDèú°+ბ–QéÑWç R]cÖÒ>0ìbWÄu0ŠæóYó“np¬“÷¥Hó–¥.HZر(2£mIxæólÆÒΜØÜ—+RóW¬&,tXû`=mC÷ƬÍZ[Žm›¸½°hhç¢]½»SJÞíåìãH;ø½¬°\ëð±#ŽGÓO|©È;­ræP•ÝÙÛÕçë.†]꺲 FèÚ‚ëÃ7¹µ=·êšîÚ×—Þ—iHklirlÞõ°ó±é“´§Õ­„6—géíûŸ×¿øúRýÕÔ×Î!]ño’ßrÞÑÞÏùàÐmÒ#Õóîcuoá§à>µ¾§ý›>û|þò¥xÀiàé ï«ð×¼!‰¡5CCÃŒáúÛ‘M#/¿Y|ËùÖø]÷ûÊïýü¹üZ>}/$(ìD6—ìEqþ›ÇÝ:X‰©ã=dH1yîäÔÄr]8x”ãã €T).sÆbãX¦«;Y€0‹Ãó   |ņ „ت‡ßXÌKJôñ –ÑÎ.cµ[ç³=H„RFRÐøþ)isÆs®Ó©ÎžÔBó¢xŠÏXþ'xgA‰`ƒ &jAT$ŒvAL¤€*R±d$‚‰d¤‚ :H«OE"H® ‚‹80`2ÖáÏ}‚ñ\0ÿMt°ç2—qY'bÓ¶²ÓmƒãÍÊÍÞ˜€<–íù£#I?ví3>¿ûþÌû”»“d¿q¿œÃ± ‚‹40‚ùx .Xs™Ë~Öaôí "²ÀŽ`¸8˜‘ý«'<ÆBPØœt.3.žGväpd ›ÅIå1¸Æd÷$Úc²¹™Ùtøý£x/ëû“IDAT•…ÐA à ÐI/æiÆW^ wÂÚ‚p¯^ÀnBb¥´çç1êt¥ø™[sB´¤T™¦!Dk]—× ïý0Ü€1–sþr‹sÎZRÊu][ñÚwÎùÙö}ŸRúóü\–åˆhŒ¹DaÇæ”Òã!qs[#¬µJ©CÔ/¨Ã€îïNßÜc }yIEND®B`‚nurpawiki-1.2.3/files/jscalendar/0000755000175000017500000000000011251252514017476 5ustar jhellstenjhellstennurpawiki-1.2.3/files/jscalendar/menuarrow2.gif0000644000175000017500000000006110726351032022264 0ustar jhellstenjhellstenGIF89a€BBBÿÿÿ!ù,„yÉÀc;nurpawiki-1.2.3/files/jscalendar/calendar-green.css0000644000175000017500000001125510726351032023064 0ustar jhellstenjhellsten/* The main calendar widget. DIV containing a table. */ div.calendar { position: relative; } .calendar, .calendar table { border: 1px solid #565; font-size: 11px; color: #000; cursor: default; background: #efe; font-family: tahoma,verdana,sans-serif; } /* Header part -- contains navigation buttons and day names. */ .calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ text-align: center; /* They are the navigation buttons */ padding: 2px; /* Make the buttons seem like they're pressing */ background: #676; color: #fff; font-size: 90%; } .calendar .nav { background: #676 url(menuarrow.gif) no-repeat 100% 100%; } .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; /* Pressing it will take you to the current date */ text-align: center; padding: 2px; background: #250; color: #efa; } .calendar thead .headrow { /* Row containing navigation buttons */ } .calendar thead .name { /* Cells containing the day names */ border-bottom: 1px solid #565; padding: 2px; text-align: center; color: #000; } .calendar thead .weekend { /* How a weekend day name shows in header */ color: #a66; } .calendar thead .hilite { /* How do the buttons in header appear when hover */ background-color: #afa; color: #000; border: 1px solid #084; padding: 1px; } .calendar thead .active { /* Active (pressed) buttons in header */ background-color: #7c7; padding: 2px 0px 0px 2px; } .calendar thead .daynames { /* Row containing the day names */ background: #dfb; } /* The body part -- contains all the days in month. */ .calendar tbody .day { /* Cells containing month days dates */ width: 2em; color: #564; text-align: right; padding: 2px 4px 2px 2px; } .calendar tbody .day.othermonth { font-size: 80%; color: #bbb; } .calendar tbody .day.othermonth.oweekend { color: #fbb; } .calendar table .wn { padding: 2px 3px 2px 2px; border-right: 1px solid #8a8; background: #dfb; } .calendar tbody .rowhilite td { background: #dfd; } .calendar tbody .rowhilite td.wn { background: #efe; } .calendar tbody td.hilite { /* Hovered cells */ background: #efd; padding: 1px 3px 1px 1px; border: 1px solid #bbb; } .calendar tbody td.active { /* Active (pressed) cells */ background: #dec; padding: 2px 2px 0px 2px; } .calendar tbody td.selected { /* Cell showing today date */ font-weight: bold; border: 1px solid #000; padding: 1px 3px 1px 1px; background: #f8fff8; color: #000; } .calendar tbody td.weekend { /* Cells showing weekend days */ color: #a66; } .calendar tbody td.today { font-weight: bold; color: #0a0; } .calendar tbody .disabled { color: #999; } .calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ visibility: hidden; } .calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ display: none; } /* The footer part -- status bar and "Close" button */ .calendar tfoot .footrow { /* The in footer (only one right now) */ text-align: center; background: #565; color: #fff; } .calendar tfoot .ttip { /* Tooltip (status bar) cell */ padding: 2px; background: #250; color: #efa; } .calendar tfoot .hilite { /* Hover style for buttons in footer */ background: #afa; border: 1px solid #084; color: #000; padding: 1px; } .calendar tfoot .active { /* Active (pressed) style for buttons in footer */ background: #7c7; padding: 2px 0px 0px 2px; } /* Combo boxes (menus that display months/years for direct selection) */ .calendar .combo { position: absolute; display: none; top: 0px; left: 0px; width: 4em; cursor: default; border: 1px solid #565; background: #efd; color: #000; font-size: 90%; z-index: 100; } .calendar .combo .label, .calendar .combo .label-IEfix { text-align: center; padding: 1px; } .calendar .combo .label-IEfix { width: 4em; } .calendar .combo .hilite { background: #af8; } .calendar .combo .active { border-top: 1px solid #6a4; border-bottom: 1px solid #6a4; background: #efe; font-weight: bold; } .calendar td.time { border-top: 1px solid #8a8; padding: 1px 0px; text-align: center; background-color: #dfb; } .calendar td.time .hour, .calendar td.time .minute, .calendar td.time .ampm { padding: 0px 3px 0px 4px; border: 1px solid #898; font-weight: bold; background-color: #fff; } .calendar td.time .ampm { text-align: center; } .calendar td.time .colon { padding: 0px 2px 0px 3px; font-weight: bold; } .calendar td.time span.hilite { border-color: #000; background-color: #686; color: #fff; } .calendar td.time span.active { border-color: #f00; background-color: #000; color: #0f0; } nurpawiki-1.2.3/files/jscalendar/calendar-win2k-1.css0000644000175000017500000001354210726351032023155 0ustar jhellstenjhellsten/* The main calendar widget. DIV containing a table. */ .calendar { position: relative; display: none; border-top: 2px solid #fff; border-right: 2px solid #000; border-bottom: 2px solid #000; border-left: 2px solid #fff; font-size: 11px; color: #000; cursor: default; background: #d4d0c8; font-family: tahoma,verdana,sans-serif; } .calendar table { border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; font-size: 11px; color: #000; cursor: default; background: #d4d0c8; font-family: tahoma,verdana,sans-serif; } /* Header part -- contains navigation buttons and day names. */ .calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ text-align: center; padding: 1px; border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; } .calendar .nav { background: transparent url(menuarrow.gif) no-repeat 100% 100%; } .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; padding: 1px; border: 1px solid #000; background: #848078; color: #fff; text-align: center; } .calendar thead .headrow { /* Row containing navigation buttons */ } .calendar thead .daynames { /* Row containing the day names */ } .calendar thead .name { /* Cells containing the day names */ border-bottom: 1px solid #000; padding: 2px; text-align: center; background: #f4f0e8; } .calendar thead .weekend { /* How a weekend day name shows in header */ color: #f00; } .calendar thead .hilite { /* How do the buttons in header appear when hover */ border-top: 2px solid #fff; border-right: 2px solid #000; border-bottom: 2px solid #000; border-left: 2px solid #fff; padding: 0px; background-color: #e4e0d8; } .calendar thead .active { /* Active (pressed) buttons in header */ padding: 2px 0px 0px 2px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; background-color: #c4c0b8; } /* The body part -- contains all the days in month. */ .calendar tbody .day { /* Cells containing month days dates */ width: 2em; text-align: right; padding: 2px 4px 2px 2px; } .calendar tbody .day.othermonth { font-size: 80%; color: #aaa; } .calendar tbody .day.othermonth.oweekend { color: #faa; } .calendar table .wn { padding: 2px 3px 2px 2px; border-right: 1px solid #000; background: #f4f0e8; } .calendar tbody .rowhilite td { background: #e4e0d8; } .calendar tbody .rowhilite td.wn { background: #d4d0c8; } .calendar tbody td.hilite { /* Hovered cells */ padding: 1px 3px 1px 1px; border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; } .calendar tbody td.active { /* Active (pressed) cells */ padding: 2px 2px 0px 2px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; } .calendar tbody td.selected { /* Cell showing selected date */ font-weight: bold; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; padding: 2px 2px 0px 2px; background: #e4e0d8; } .calendar tbody td.weekend { /* Cells showing weekend days */ color: #f00; } .calendar tbody td.today { /* Cell showing today date */ font-weight: bold; color: #00f; } .calendar tbody .disabled { color: #999; } .calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ visibility: hidden; } .calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ display: none; } /* The footer part -- status bar and "Close" button */ .calendar tfoot .footrow { /* The in footer (only one right now) */ } .calendar tfoot .ttip { /* Tooltip (status bar) cell */ background: #f4f0e8; padding: 1px; border: 1px solid #000; background: #848078; color: #fff; text-align: center; } .calendar tfoot .hilite { /* Hover style for buttons in footer */ border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; padding: 1px; background: #e4e0d8; } .calendar tfoot .active { /* Active (pressed) style for buttons in footer */ padding: 2px 0px 0px 2px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; } /* Combo boxes (menus that display months/years for direct selection) */ .calendar .combo { position: absolute; display: none; width: 4em; top: 0px; left: 0px; cursor: default; border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; background: #e4e0d8; font-size: 90%; padding: 1px; z-index: 100; } .calendar .combo .label, .calendar .combo .label-IEfix { text-align: center; padding: 1px; } .calendar .combo .label-IEfix { width: 4em; } .calendar .combo .active { background: #c4c0b8; padding: 0px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; } .calendar .combo .hilite { background: #048; color: #fea; } .calendar td.time { border-top: 1px solid #000; padding: 1px 0px; text-align: center; background-color: #f4f0e8; } .calendar td.time .hour, .calendar td.time .minute, .calendar td.time .ampm { padding: 0px 3px 0px 4px; border: 1px solid #889; font-weight: bold; background-color: #fff; } .calendar td.time .ampm { text-align: center; } .calendar td.time .colon { padding: 0px 2px 0px 3px; font-weight: bold; } .calendar td.time span.hilite { border-color: #000; background-color: #766; color: #fff; } .calendar td.time span.active { border-color: #f00; background-color: #000; color: #0f0; } nurpawiki-1.2.3/files/jscalendar/img.gif0000644000175000017500000000033710726351032020745 0ustar jhellstenjhellstenGIF89aò000ÿÜÜÜÿÿÀÿÿÿÿÿÿ!ù,¤XUU…UUUXUU…U€U€333833ƒ33PX03ƒ333833ƒP€U€DDDHDD„DDPX@„@@„PDHDD„DDDHU€@H€APX@D„DDDHDD„P@€@U€DDDHDD„DDPX€€PUUXUU…UUUXU•;nurpawiki-1.2.3/files/jscalendar/calendar-tas.css0000644000175000017500000001227510726351032022556 0ustar jhellstenjhellsten/* The main calendar widget. DIV containing a table. */ div.calendar { position: relative; } .calendar, .calendar table { border: 1px solid #655; font-size: 11px; color: #000; cursor: default; background: #ffd; font-family: tahoma,verdana,sans-serif; filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#DDDCCC,EndColorStr=#FFFFFF); } /* Header part -- contains navigation buttons and day names. */ .calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ text-align: center; /* They are the navigation buttons */ padding: 2px; /* Make the buttons seem like they're pressing */ color:#363636; } .calendar .nav { background: #edc url(menuarrow.gif) no-repeat 100% 100%; } .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; /* Pressing it will take you to the current date */ text-align: center; background: #654; color: #363636; padding: 2px; filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#ffffff,EndColorStr=#dddccc); } .calendar thead .headrow { /* Row containing navigation buttons */ /*background: #3B86A0;*/ color: #363636; font-weight: bold; filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#ffffff,EndColorStr=#3b86a0); } .calendar thead .name { /* Cells containing the day names */ border-bottom: 1px solid #655; padding: 2px; text-align: center; color: #363636; filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#DDDCCC,EndColorStr=#FFFFFF); } .calendar thead .weekend { /* How a weekend day name shows in header */ color: #f00; } .calendar thead .hilite { /* How do the buttons in header appear when hover */ background-color: #ffcc86; color: #000; border: 1px solid #b59345; padding: 1px; } .calendar thead .active { /* Active (pressed) buttons in header */ background-color: #c77; padding: 2px 0px 0px 2px; } .calendar thead .daynames { /* Row containing the day names */ background: #fed; } /* The body part -- contains all the days in month. */ .calendar tbody .day { /* Cells containing month days dates */ width: 2em; text-align: right; padding: 2px 4px 2px 2px; } .calendar tbody .day.othermonth { font-size: 80%; color: #aaa; } .calendar tbody .day.othermonth.oweekend { color: #faa; } .calendar table .wn { padding: 2px 3px 2px 2px; border-right: 1px solid #000; background: #fed; } .calendar tbody .rowhilite td { background: #ddf; } .calendar tbody .rowhilite td.wn { background: #efe; } .calendar tbody td.hilite { /* Hovered cells */ background: #ffe; padding: 1px 3px 1px 1px; border: 1px solid #bbb; } .calendar tbody td.active { /* Active (pressed) cells */ background: #ddc; padding: 2px 2px 0px 2px; } .calendar tbody td.selected { /* Cell showing today date */ font-weight: bold; border: 1px solid #000; padding: 1px 3px 1px 1px; background: #fea; } .calendar tbody td.weekend { /* Cells showing weekend days */ color: #f00; } .calendar tbody td.today { font-weight: bold; } .calendar tbody .disabled { color: #999; } .calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ visibility: hidden; } .calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ display: none; } /* The footer part -- status bar and "Close" button */ .calendar tfoot .footrow { /* The in footer (only one right now) */ text-align: center; background: #988; color: #000; } .calendar tfoot .ttip { /* Tooltip (status bar) cell */ border-top: 1px solid #655; background: #dcb; color: #363636; font-weight: bold; filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#FFFFFF,EndColorStr=#DDDCCC); } .calendar tfoot .hilite { /* Hover style for buttons in footer */ background: #faa; border: 1px solid #f40; padding: 1px; } .calendar tfoot .active { /* Active (pressed) style for buttons in footer */ background: #c77; padding: 2px 0px 0px 2px; } /* Combo boxes (menus that display months/years for direct selection) */ .combo { position: absolute; display: none; top: 0px; left: 0px; width: 4em; cursor: default; border: 1px solid #655; background: #ffe; color: #000; font-size: smaller; z-index: 100; } .combo .label, .combo .label-IEfix { text-align: center; padding: 1px; } .combo .label-IEfix { width: 4em; } .combo .hilite { background: #fc8; } .combo .active { border-top: 1px solid #a64; border-bottom: 1px solid #a64; background: #fee; font-weight: bold; } .calendar td.time { border-top: 1px solid #a88; padding: 1px 0px; text-align: center; background-color: #fed; } .calendar td.time .hour, .calendar td.time .minute, .calendar td.time .ampm { padding: 0px 3px 0px 4px; border: 1px solid #988; font-weight: bold; background-color: #fff; } .calendar td.time .ampm { text-align: center; } .calendar td.time .colon { padding: 0px 2px 0px 3px; font-weight: bold; } .calendar td.time span.hilite { border-color: #000; background-color: #866; color: #fff; } .calendar td.time span.active { border-color: #f00; background-color: #000; color: #0f0; } nurpawiki-1.2.3/files/jscalendar/calendar_stripped.js0000644000175000017500000010301310726351032023516 0ustar jhellstenjhellsten/* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo * ----------------------------------------------------------- * * The DHTML Calendar, version 1.0 "It is happening again" * * Details and latest version at: * www.dynarch.com/projects/calendar * * This script is developed by Dynarch.com. Visit us at www.dynarch.com. * * This script is distributed under the GNU Lesser General Public License. * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html */ Calendar=function(firstDayOfWeek,dateStr,onSelected,onClose){this.activeDiv=null;this.currentDateEl=null;this.getDateStatus=null;this.getDateToolTip=null;this.getDateText=null;this.timeout=null;this.onSelected=onSelected||null;this.onClose=onClose||null;this.dragging=false;this.hidden=false;this.minYear=1970;this.maxYear=2050;this.dateFormat=Calendar._TT["DEF_DATE_FORMAT"];this.ttDateFormat=Calendar._TT["TT_DATE_FORMAT"];this.isPopup=true;this.weekNumbers=true;this.firstDayOfWeek=typeof firstDayOfWeek=="number"?firstDayOfWeek:Calendar._FD;this.showsOtherMonths=false;this.dateStr=dateStr;this.ar_days=null;this.showsTime=false;this.time24=true;this.yearStep=2;this.hiliteToday=true;this.multiple=null;this.table=null;this.element=null;this.tbody=null;this.firstdayname=null;this.monthsCombo=null;this.yearsCombo=null;this.hilitedMonth=null;this.activeMonth=null;this.hilitedYear=null;this.activeYear=null;this.dateClicked=false;if(typeof Calendar._SDN=="undefined"){if(typeof Calendar._SDN_len=="undefined")Calendar._SDN_len=3;var ar=new Array();for(var i=8;i>0;){ar[--i]=Calendar._DN[i].substr(0,Calendar._SDN_len);}Calendar._SDN=ar;if(typeof Calendar._SMN_len=="undefined")Calendar._SMN_len=3;ar=new Array();for(var i=12;i>0;){ar[--i]=Calendar._MN[i].substr(0,Calendar._SMN_len);}Calendar._SMN=ar;}};Calendar._C=null;Calendar.is_ie=(/msie/i.test(navigator.userAgent)&&!/opera/i.test(navigator.userAgent));Calendar.is_ie5=(Calendar.is_ie&&/msie 5\.0/i.test(navigator.userAgent));Calendar.is_opera=/opera/i.test(navigator.userAgent);Calendar.is_khtml=/Konqueror|Safari|KHTML/i.test(navigator.userAgent);Calendar.getAbsolutePos=function(el){var SL=0,ST=0;var is_div=/^div$/i.test(el.tagName);if(is_div&&el.scrollLeft)SL=el.scrollLeft;if(is_div&&el.scrollTop)ST=el.scrollTop;var r={x:el.offsetLeft-SL,y:el.offsetTop-ST};if(el.offsetParent){var tmp=this.getAbsolutePos(el.offsetParent);r.x+=tmp.x;r.y+=tmp.y;}return r;};Calendar.isRelated=function(el,evt){var related=evt.relatedTarget;if(!related){var type=evt.type;if(type=="mouseover"){related=evt.fromElement;}else if(type=="mouseout"){related=evt.toElement;}}while(related){if(related==el){return true;}related=related.parentNode;}return false;};Calendar.removeClass=function(el,className){if(!(el&&el.className)){return;}var cls=el.className.split(" ");var ar=new Array();for(var i=cls.length;i>0;){if(cls[--i]!=className){ar[ar.length]=cls[i];}}el.className=ar.join(" ");};Calendar.addClass=function(el,className){Calendar.removeClass(el,className);el.className+=" "+className;};Calendar.getElement=function(ev){var f=Calendar.is_ie?window.event.srcElement:ev.currentTarget;while(f.nodeType!=1||/^div$/i.test(f.tagName))f=f.parentNode;return f;};Calendar.getTargetElement=function(ev){var f=Calendar.is_ie?window.event.srcElement:ev.target;while(f.nodeType!=1)f=f.parentNode;return f;};Calendar.stopEvent=function(ev){ev||(ev=window.event);if(Calendar.is_ie){ev.cancelBubble=true;ev.returnValue=false;}else{ev.preventDefault();ev.stopPropagation();}return false;};Calendar.addEvent=function(el,evname,func){if(el.attachEvent){el.attachEvent("on"+evname,func);}else if(el.addEventListener){el.addEventListener(evname,func,true);}else{el["on"+evname]=func;}};Calendar.removeEvent=function(el,evname,func){if(el.detachEvent){el.detachEvent("on"+evname,func);}else if(el.removeEventListener){el.removeEventListener(evname,func,true);}else{el["on"+evname]=null;}};Calendar.createElement=function(type,parent){var el=null;if(document.createElementNS){el=document.createElementNS("http://www.w3.org/1999/xhtml",type);}else{el=document.createElement(type);}if(typeof parent!="undefined"){parent.appendChild(el);}return el;};Calendar._add_evs=function(el){with(Calendar){addEvent(el,"mouseover",dayMouseOver);addEvent(el,"mousedown",dayMouseDown);addEvent(el,"mouseout",dayMouseOut);if(is_ie){addEvent(el,"dblclick",dayMouseDblClick);el.setAttribute("unselectable",true);}}};Calendar.findMonth=function(el){if(typeof el.month!="undefined"){return el;}else if(typeof el.parentNode.month!="undefined"){return el.parentNode;}return null;};Calendar.findYear=function(el){if(typeof el.year!="undefined"){return el;}else if(typeof el.parentNode.year!="undefined"){return el.parentNode;}return null;};Calendar.showMonthsCombo=function(){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var mc=cal.monthsCombo;if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}if(cal.activeMonth){Calendar.removeClass(cal.activeMonth,"active");}var mon=cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];Calendar.addClass(mon,"active");cal.activeMonth=mon;var s=mc.style;s.display="block";if(cd.navtype<0)s.left=cd.offsetLeft+"px";else{var mcw=mc.offsetWidth;if(typeof mcw=="undefined")mcw=50;s.left=(cd.offsetLeft+cd.offsetWidth-mcw)+"px";}s.top=(cd.offsetTop+cd.offsetHeight)+"px";};Calendar.showYearsCombo=function(fwd){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var yc=cal.yearsCombo;if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}if(cal.activeYear){Calendar.removeClass(cal.activeYear,"active");}cal.activeYear=null;var Y=cal.date.getFullYear()+(fwd?1:-1);var yr=yc.firstChild;var show=false;for(var i=12;i>0;--i){if(Y>=cal.minYear&&Y<=cal.maxYear){yr.innerHTML=Y;yr.year=Y;yr.style.display="block";show=true;}else{yr.style.display="none";}yr=yr.nextSibling;Y+=fwd?cal.yearStep:-cal.yearStep;}if(show){var s=yc.style;s.display="block";if(cd.navtype<0)s.left=cd.offsetLeft+"px";else{var ycw=yc.offsetWidth;if(typeof ycw=="undefined")ycw=50;s.left=(cd.offsetLeft+cd.offsetWidth-ycw)+"px";}s.top=(cd.offsetTop+cd.offsetHeight)+"px";}};Calendar.tableMouseUp=function(ev){var cal=Calendar._C;if(!cal){return false;}if(cal.timeout){clearTimeout(cal.timeout);}var el=cal.activeDiv;if(!el){return false;}var target=Calendar.getTargetElement(ev);ev||(ev=window.event);Calendar.removeClass(el,"active");if(target==el||target.parentNode==el){Calendar.cellClick(el,ev);}var mon=Calendar.findMonth(target);var date=null;if(mon){date=new Date(cal.date);if(mon.month!=date.getMonth()){date.setMonth(mon.month);cal.setDate(date);cal.dateClicked=false;cal.callHandler();}}else{var year=Calendar.findYear(target);if(year){date=new Date(cal.date);if(year.year!=date.getFullYear()){date.setFullYear(year.year);cal.setDate(date);cal.dateClicked=false;cal.callHandler();}}}with(Calendar){removeEvent(document,"mouseup",tableMouseUp);removeEvent(document,"mouseover",tableMouseOver);removeEvent(document,"mousemove",tableMouseOver);cal._hideCombos();_C=null;return stopEvent(ev);}};Calendar.tableMouseOver=function(ev){var cal=Calendar._C;if(!cal){return;}var el=cal.activeDiv;var target=Calendar.getTargetElement(ev);if(target==el||target.parentNode==el){Calendar.addClass(el,"hilite active");Calendar.addClass(el.parentNode,"rowhilite");}else{if(typeof el.navtype=="undefined"||(el.navtype!=50&&(el.navtype==0||Math.abs(el.navtype)>2)))Calendar.removeClass(el,"active");Calendar.removeClass(el,"hilite");Calendar.removeClass(el.parentNode,"rowhilite");}ev||(ev=window.event);if(el.navtype==50&&target!=el){var pos=Calendar.getAbsolutePos(el);var w=el.offsetWidth;var x=ev.clientX;var dx;var decrease=true;if(x>pos.x+w){dx=x-pos.x-w;decrease=false;}else dx=pos.x-x;if(dx<0)dx=0;var range=el._range;var current=el._current;var count=Math.floor(dx/10)%range.length;for(var i=range.length;--i>=0;)if(range[i]==current)break;while(count-->0)if(decrease){if(--i<0)i=range.length-1;}else if(++i>=range.length)i=0;var newval=range[i];el.innerHTML=newval;cal.onUpdateTime();}var mon=Calendar.findMonth(target);if(mon){if(mon.month!=cal.date.getMonth()){if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}Calendar.addClass(mon,"hilite");cal.hilitedMonth=mon;}else if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}}else{if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}var year=Calendar.findYear(target);if(year){if(year.year!=cal.date.getFullYear()){if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}Calendar.addClass(year,"hilite");cal.hilitedYear=year;}else if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}else if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}return Calendar.stopEvent(ev);};Calendar.tableMouseDown=function(ev){if(Calendar.getTargetElement(ev)==Calendar.getElement(ev)){return Calendar.stopEvent(ev);}};Calendar.calDragIt=function(ev){var cal=Calendar._C;if(!(cal&&cal.dragging)){return false;}var posX;var posY;if(Calendar.is_ie){posY=window.event.clientY+document.body.scrollTop;posX=window.event.clientX+document.body.scrollLeft;}else{posX=ev.pageX;posY=ev.pageY;}cal.hideShowCovered();var st=cal.element.style;st.left=(posX-cal.xOffs)+"px";st.top=(posY-cal.yOffs)+"px";return Calendar.stopEvent(ev);};Calendar.calDragEnd=function(ev){var cal=Calendar._C;if(!cal){return false;}cal.dragging=false;with(Calendar){removeEvent(document,"mousemove",calDragIt);removeEvent(document,"mouseup",calDragEnd);tableMouseUp(ev);}cal.hideShowCovered();};Calendar.dayMouseDown=function(ev){var el=Calendar.getElement(ev);if(el.disabled){return false;}var cal=el.calendar;cal.activeDiv=el;Calendar._C=cal;if(el.navtype!=300)with(Calendar){if(el.navtype==50){el._current=el.innerHTML;addEvent(document,"mousemove",tableMouseOver);}else addEvent(document,Calendar.is_ie5?"mousemove":"mouseover",tableMouseOver);addClass(el,"hilite active");addEvent(document,"mouseup",tableMouseUp);}else if(cal.isPopup){cal._dragStart(ev);}if(el.navtype==-1||el.navtype==1){if(cal.timeout)clearTimeout(cal.timeout);cal.timeout=setTimeout("Calendar.showMonthsCombo()",250);}else if(el.navtype==-2||el.navtype==2){if(cal.timeout)clearTimeout(cal.timeout);cal.timeout=setTimeout((el.navtype>0)?"Calendar.showYearsCombo(true)":"Calendar.showYearsCombo(false)",250);}else{cal.timeout=null;}return Calendar.stopEvent(ev);};Calendar.dayMouseDblClick=function(ev){Calendar.cellClick(Calendar.getElement(ev),ev||window.event);if(Calendar.is_ie){document.selection.empty();}};Calendar.dayMouseOver=function(ev){var el=Calendar.getElement(ev);if(Calendar.isRelated(el,ev)||Calendar._C||el.disabled){return false;}if(el.ttip){if(el.ttip.substr(0,1)=="_"){el.ttip=el.caldate.print(el.calendar.ttDateFormat)+el.ttip.substr(1);}el.calendar.tooltips.innerHTML=el.ttip;}if(el.navtype!=300){Calendar.addClass(el,"hilite");if(el.caldate){Calendar.addClass(el.parentNode,"rowhilite");}}return Calendar.stopEvent(ev);};Calendar.dayMouseOut=function(ev){with(Calendar){var el=getElement(ev);if(isRelated(el,ev)||_C||el.disabled)return false;removeClass(el,"hilite");if(el.caldate)removeClass(el.parentNode,"rowhilite");if(el.calendar)el.calendar.tooltips.innerHTML=_TT["SEL_DATE"];return stopEvent(ev);}};Calendar.cellClick=function(el,ev){var cal=el.calendar;var closing=false;var newdate=false;var date=null;if(typeof el.navtype=="undefined"){if(cal.currentDateEl){Calendar.removeClass(cal.currentDateEl,"selected");Calendar.addClass(el,"selected");closing=(cal.currentDateEl==el);if(!closing){cal.currentDateEl=el;}}cal.date.setDateOnly(el.caldate);date=cal.date;var other_month=!(cal.dateClicked=!el.otherMonth);if(!other_month&&!cal.currentDateEl)cal._toggleMultipleDate(new Date(date));else newdate=!el.disabled;if(other_month)cal._init(cal.firstDayOfWeek,date);}else{if(el.navtype==200){Calendar.removeClass(el,"hilite");cal.callCloseHandler();return;}date=new Date(cal.date);if(el.navtype==0)date.setDateOnly(new Date());cal.dateClicked=false;var year=date.getFullYear();var mon=date.getMonth();function setMonth(m){var day=date.getDate();var max=date.getMonthDays(m);if(day>max){date.setDate(max);}date.setMonth(m);};switch(el.navtype){case 400:Calendar.removeClass(el,"hilite");var text=Calendar._TT["ABOUT"];if(typeof text!="undefined"){text+=cal.showsTime?Calendar._TT["ABOUT_TIME"]:"";}else{text="Help and about box text is not translated into this language.\n"+"If you know this language and you feel generous please update\n"+"the corresponding file in \"lang\" subdir to match calendar-en.js\n"+"and send it back to to get it into the distribution ;-)\n\n"+"Thank you!\n"+"http://dynarch.com/mishoo/calendar.epl\n";}alert(text);return;case-2:if(year>cal.minYear){date.setFullYear(year-1);}break;case-1:if(mon>0){setMonth(mon-1);}else if(year-->cal.minYear){date.setFullYear(year);setMonth(11);}break;case 1:if(mon<11){setMonth(mon+1);}else if(year=0;)if(range[i]==current)break;if(ev&&ev.shiftKey){if(--i<0)i=range.length-1;}else if(++i>=range.length)i=0;var newval=range[i];el.innerHTML=newval;cal.onUpdateTime();return;case 0:if((typeof cal.getDateStatus=="function")&&cal.getDateStatus(date,date.getFullYear(),date.getMonth(),date.getDate())){return false;}break;}if(!date.equalsTo(cal.date)){cal.setDate(date);newdate=true;}else if(el.navtype==0)newdate=closing=true;}if(newdate){ev&&cal.callHandler();}if(closing){Calendar.removeClass(el,"hilite");ev&&cal.callCloseHandler();}};Calendar.prototype.create=function(_par){var parent=null;if(!_par){parent=document.getElementsByTagName("body")[0];this.isPopup=true;}else{parent=_par;this.isPopup=false;}this.date=this.dateStr?new Date(this.dateStr):new Date();var table=Calendar.createElement("table");this.table=table;table.cellSpacing=0;table.cellPadding=0;table.calendar=this;Calendar.addEvent(table,"mousedown",Calendar.tableMouseDown);var div=Calendar.createElement("div");this.element=div;div.className="calendar";if(this.isPopup){div.style.position="absolute";div.style.display="none";}div.appendChild(table);var thead=Calendar.createElement("thead",table);var cell=null;var row=null;var cal=this;var hh=function(text,cs,navtype){cell=Calendar.createElement("td",row);cell.colSpan=cs;cell.className="button";if(navtype!=0&&Math.abs(navtype)<=2)cell.className+=" nav";Calendar._add_evs(cell);cell.calendar=cal;cell.navtype=navtype;cell.innerHTML="
"+text+"
";return cell;};row=Calendar.createElement("tr",thead);var title_length=6;(this.isPopup)&&--title_length;(this.weekNumbers)&&++title_length;hh("?",1,400).ttip=Calendar._TT["INFO"];this.title=hh("",title_length,300);this.title.className="title";if(this.isPopup){this.title.ttip=Calendar._TT["DRAG_TO_MOVE"];this.title.style.cursor="move";hh("×",1,200).ttip=Calendar._TT["CLOSE"];}row=Calendar.createElement("tr",thead);row.className="headrow";this._nav_py=hh("«",1,-2);this._nav_py.ttip=Calendar._TT["PREV_YEAR"];this._nav_pm=hh("‹",1,-1);this._nav_pm.ttip=Calendar._TT["PREV_MONTH"];this._nav_now=hh(Calendar._TT["TODAY"],this.weekNumbers?4:3,0);this._nav_now.ttip=Calendar._TT["GO_TODAY"];this._nav_nm=hh("›",1,1);this._nav_nm.ttip=Calendar._TT["NEXT_MONTH"];this._nav_ny=hh("»",1,2);this._nav_ny.ttip=Calendar._TT["NEXT_YEAR"];row=Calendar.createElement("tr",thead);row.className="daynames";if(this.weekNumbers){cell=Calendar.createElement("td",row);cell.className="name wn";cell.innerHTML=Calendar._TT["WK"];}for(var i=7;i>0;--i){cell=Calendar.createElement("td",row);if(!i){cell.navtype=100;cell.calendar=this;Calendar._add_evs(cell);}}this.firstdayname=(this.weekNumbers)?row.firstChild.nextSibling:row.firstChild;this._displayWeekdays();var tbody=Calendar.createElement("tbody",table);this.tbody=tbody;for(i=6;i>0;--i){row=Calendar.createElement("tr",tbody);if(this.weekNumbers){cell=Calendar.createElement("td",row);}for(var j=7;j>0;--j){cell=Calendar.createElement("td",row);cell.calendar=this;Calendar._add_evs(cell);}}if(this.showsTime){row=Calendar.createElement("tr",tbody);row.className="time";cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=2;cell.innerHTML=Calendar._TT["TIME"]||" ";cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=this.weekNumbers?4:3;(function(){function makeTimePart(className,init,range_start,range_end){var part=Calendar.createElement("span",cell);part.className=className;part.innerHTML=init;part.calendar=cal;part.ttip=Calendar._TT["TIME_PART"];part.navtype=50;part._range=[];if(typeof range_start!="number")part._range=range_start;else{for(var i=range_start;i<=range_end;++i){var txt;if(i<10&&range_end>=10)txt='0'+i;else txt=''+i;part._range[part._range.length]=txt;}}Calendar._add_evs(part);return part;};var hrs=cal.date.getHours();var mins=cal.date.getMinutes();var t12=!cal.time24;var pm=(hrs>12);if(t12&&pm)hrs-=12;var H=makeTimePart("hour",hrs,t12?1:0,t12?12:23);var span=Calendar.createElement("span",cell);span.innerHTML=":";span.className="colon";var M=makeTimePart("minute",mins,0,59);var AP=null;cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=2;if(t12)AP=makeTimePart("ampm",pm?"pm":"am",["am","pm"]);else cell.innerHTML=" ";cal.onSetTime=function(){var pm,hrs=this.date.getHours(),mins=this.date.getMinutes();if(t12){pm=(hrs>=12);if(pm)hrs-=12;if(hrs==0)hrs=12;AP.innerHTML=pm?"pm":"am";}H.innerHTML=(hrs<10)?("0"+hrs):hrs;M.innerHTML=(mins<10)?("0"+mins):mins;};cal.onUpdateTime=function(){var date=this.date;var h=parseInt(H.innerHTML,10);if(t12){if(/pm/i.test(AP.innerHTML)&&h<12)h+=12;else if(/am/i.test(AP.innerHTML)&&h==12)h=0;}var d=date.getDate();var m=date.getMonth();var y=date.getFullYear();date.setHours(h);date.setMinutes(parseInt(M.innerHTML,10));date.setFullYear(y);date.setMonth(m);date.setDate(d);this.dateClicked=false;this.callHandler();};})();}else{this.onSetTime=this.onUpdateTime=function(){};}var tfoot=Calendar.createElement("tfoot",table);row=Calendar.createElement("tr",tfoot);row.className="footrow";cell=hh(Calendar._TT["SEL_DATE"],this.weekNumbers?8:7,300);cell.className="ttip";if(this.isPopup){cell.ttip=Calendar._TT["DRAG_TO_MOVE"];cell.style.cursor="move";}this.tooltips=cell;div=Calendar.createElement("div",this.element);this.monthsCombo=div;div.className="combo";for(i=0;i0;--i){var yr=Calendar.createElement("div");yr.className=Calendar.is_ie?"label-IEfix":"label";div.appendChild(yr);}this._init(this.firstDayOfWeek,this.date);parent.appendChild(this.element);};Calendar._keyEvent=function(ev){var cal=window._dynarch_popupCalendar;if(!cal||cal.multiple)return false;(Calendar.is_ie)&&(ev=window.event);var act=(Calendar.is_ie||ev.type=="keypress"),K=ev.keyCode;if(ev.ctrlKey){switch(K){case 37:act&&Calendar.cellClick(cal._nav_pm);break;case 38:act&&Calendar.cellClick(cal._nav_py);break;case 39:act&&Calendar.cellClick(cal._nav_nm);break;case 40:act&&Calendar.cellClick(cal._nav_ny);break;default:return false;}}else switch(K){case 32:Calendar.cellClick(cal._nav_now);break;case 27:act&&cal.callCloseHandler();break;case 37:case 38:case 39:case 40:if(act){var prev,x,y,ne,el,step;prev=K==37||K==38;step=(K==37||K==39)?1:7;function setVars(){el=cal.currentDateEl;var p=el.pos;x=p&15;y=p>>4;ne=cal.ar_days[y][x];};setVars();function prevMonth(){var date=new Date(cal.date);date.setDate(date.getDate()-step);cal.setDate(date);};function nextMonth(){var date=new Date(cal.date);date.setDate(date.getDate()+step);cal.setDate(date);};while(1){switch(K){case 37:if(--x>=0)ne=cal.ar_days[y][x];else{x=6;K=38;continue;}break;case 38:if(--y>=0)ne=cal.ar_days[y][x];else{prevMonth();setVars();}break;case 39:if(++x<7)ne=cal.ar_days[y][x];else{x=0;K=40;continue;}break;case 40:if(++ythis.maxYear){year=this.maxYear;date.setFullYear(year);}this.firstDayOfWeek=firstDayOfWeek;this.date=new Date(date);var month=date.getMonth();var mday=date.getDate();var no_days=date.getMonthDays();date.setDate(1);var day1=(date.getDay()-this.firstDayOfWeek)%7;if(day1<0)day1+=7;date.setDate(-day1);date.setDate(date.getDate()+1);var row=this.tbody.firstChild;var MN=Calendar._SMN[month];var ar_days=this.ar_days=new Array();var weekend=Calendar._TT["WEEKEND"];var dates=this.multiple?(this.datesCells={}):null;for(var i=0;i<6;++i,row=row.nextSibling){var cell=row.firstChild;if(this.weekNumbers){cell.className="day wn";cell.innerHTML=date.getWeekNumber();cell=cell.nextSibling;}row.className="daysrow";var hasdays=false,iday,dpos=ar_days[i]=[];for(var j=0;j<7;++j,cell=cell.nextSibling,date.setDate(iday+1)){iday=date.getDate();var wday=date.getDay();cell.className="day";cell.pos=i<<4|j;dpos[j]=cell;var current_month=(date.getMonth()==month);if(!current_month){if(this.showsOtherMonths){cell.className+=" othermonth";cell.otherMonth=true;}else{cell.className="emptycell";cell.innerHTML=" ";cell.disabled=true;continue;}}else{cell.otherMonth=false;hasdays=true;}cell.disabled=false;cell.innerHTML=this.getDateText?this.getDateText(date,iday):iday;if(dates)dates[date.print("%Y%m%d")]=cell;if(this.getDateStatus){var status=this.getDateStatus(date,year,month,iday);if(this.getDateToolTip){var toolTip=this.getDateToolTip(date,year,month,iday);if(toolTip)cell.title=toolTip;}if(status===true){cell.className+=" disabled";cell.disabled=true;}else{if(/disabled/i.test(status))cell.disabled=true;cell.className+=" "+status;}}if(!cell.disabled){cell.caldate=new Date(date);cell.ttip="_";if(!this.multiple&¤t_month&&iday==mday&&this.hiliteToday){cell.className+=" selected";this.currentDateEl=cell;}if(date.getFullYear()==TY&&date.getMonth()==TM&&iday==TD){cell.className+=" today";cell.ttip+=Calendar._TT["PART_TODAY"];}if(weekend.indexOf(wday.toString())!=-1)cell.className+=cell.otherMonth?" oweekend":" weekend";}}if(!(hasdays||this.showsOtherMonths))row.className="emptyrow";}this.title.innerHTML=Calendar._MN[month]+", "+year;this.onSetTime();this.table.style.visibility="visible";this._initMultipleDates();};Calendar.prototype._initMultipleDates=function(){if(this.multiple){for(var i in this.multiple){var cell=this.datesCells[i];var d=this.multiple[i];if(!d)continue;if(cell)cell.className+=" selected";}}};Calendar.prototype._toggleMultipleDate=function(date){if(this.multiple){var ds=date.print("%Y%m%d");var cell=this.datesCells[ds];if(cell){var d=this.multiple[ds];if(!d){Calendar.addClass(cell,"selected");this.multiple[ds]=date;}else{Calendar.removeClass(cell,"selected");delete this.multiple[ds];}}}};Calendar.prototype.setDateToolTipHandler=function(unaryFunction){this.getDateToolTip=unaryFunction;};Calendar.prototype.setDate=function(date){if(!date.equalsTo(this.date)){this._init(this.firstDayOfWeek,date);}};Calendar.prototype.refresh=function(){this._init(this.firstDayOfWeek,this.date);};Calendar.prototype.setFirstDayOfWeek=function(firstDayOfWeek){this._init(firstDayOfWeek,this.date);this._displayWeekdays();};Calendar.prototype.setDateStatusHandler=Calendar.prototype.setDisabledHandler=function(unaryFunction){this.getDateStatus=unaryFunction;};Calendar.prototype.setRange=function(a,z){this.minYear=a;this.maxYear=z;};Calendar.prototype.callHandler=function(){if(this.onSelected){this.onSelected(this,this.date.print(this.dateFormat));}};Calendar.prototype.callCloseHandler=function(){if(this.onClose){this.onClose(this);}this.hideShowCovered();};Calendar.prototype.destroy=function(){var el=this.element.parentNode;el.removeChild(this.element);Calendar._C=null;window._dynarch_popupCalendar=null;};Calendar.prototype.reparent=function(new_parent){var el=this.element;el.parentNode.removeChild(el);new_parent.appendChild(el);};Calendar._checkCalendar=function(ev){var calendar=window._dynarch_popupCalendar;if(!calendar){return false;}var el=Calendar.is_ie?Calendar.getElement(ev):Calendar.getTargetElement(ev);for(;el!=null&&el!=calendar.element;el=el.parentNode);if(el==null){window._dynarch_popupCalendar.callCloseHandler();return Calendar.stopEvent(ev);}};Calendar.prototype.show=function(){var rows=this.table.getElementsByTagName("tr");for(var i=rows.length;i>0;){var row=rows[--i];Calendar.removeClass(row,"rowhilite");var cells=row.getElementsByTagName("td");for(var j=cells.length;j>0;){var cell=cells[--j];Calendar.removeClass(cell,"hilite");Calendar.removeClass(cell,"active");}}this.element.style.display="block";this.hidden=false;if(this.isPopup){window._dynarch_popupCalendar=this;Calendar.addEvent(document,"keydown",Calendar._keyEvent);Calendar.addEvent(document,"keypress",Calendar._keyEvent);Calendar.addEvent(document,"mousedown",Calendar._checkCalendar);}this.hideShowCovered();};Calendar.prototype.hide=function(){if(this.isPopup){Calendar.removeEvent(document,"keydown",Calendar._keyEvent);Calendar.removeEvent(document,"keypress",Calendar._keyEvent);Calendar.removeEvent(document,"mousedown",Calendar._checkCalendar);}this.element.style.display="none";this.hidden=true;this.hideShowCovered();};Calendar.prototype.showAt=function(x,y){var s=this.element.style;s.left=x+"px";s.top=y+"px";this.show();};Calendar.prototype.showAtElement=function(el,opts){var self=this;var p=Calendar.getAbsolutePos(el);if(!opts||typeof opts!="string"){this.showAt(p.x,p.y+el.offsetHeight);return true;}function fixPosition(box){if(box.x<0)box.x=0;if(box.y<0)box.y=0;var cp=document.createElement("div");var s=cp.style;s.position="absolute";s.right=s.bottom=s.width=s.height="0px";document.body.appendChild(cp);var br=Calendar.getAbsolutePos(cp);document.body.removeChild(cp);if(Calendar.is_ie){br.y+=document.body.scrollTop;br.x+=document.body.scrollLeft;}else{br.y+=window.scrollY;br.x+=window.scrollX;}var tmp=box.x+box.width-br.x;if(tmp>0)box.x-=tmp;tmp=box.y+box.height-br.y;if(tmp>0)box.y-=tmp;};this.element.style.display="block";Calendar.continuation_for_the_fucking_khtml_browser=function(){var w=self.element.offsetWidth;var h=self.element.offsetHeight;self.element.style.display="none";var valign=opts.substr(0,1);var halign="l";if(opts.length>1){halign=opts.substr(1,1);}switch(valign){case "T":p.y-=h;break;case "B":p.y+=el.offsetHeight;break;case "C":p.y+=(el.offsetHeight-h)/2;break;case "t":p.y+=el.offsetHeight-h;break;case "b":break;}switch(halign){case "L":p.x-=w;break;case "R":p.x+=el.offsetWidth;break;case "C":p.x+=(el.offsetWidth-w)/2;break;case "l":p.x+=el.offsetWidth-w;break;case "r":break;}p.width=w;p.height=h+40;self.monthsCombo.style.display="none";fixPosition(p);self.showAt(p.x,p.y);};if(Calendar.is_khtml)setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()",10);else Calendar.continuation_for_the_fucking_khtml_browser();};Calendar.prototype.setDateFormat=function(str){this.dateFormat=str;};Calendar.prototype.setTtDateFormat=function(str){this.ttDateFormat=str;};Calendar.prototype.parseDate=function(str,fmt){if(!fmt)fmt=this.dateFormat;this.setDate(Date.parseDate(str,fmt));};Calendar.prototype.hideShowCovered=function(){if(!Calendar.is_ie&&!Calendar.is_opera)return;function getVisib(obj){var value=obj.style.visibility;if(!value){if(document.defaultView&&typeof(document.defaultView.getComputedStyle)=="function"){if(!Calendar.is_khtml)value=document.defaultView. getComputedStyle(obj,"").getPropertyValue("visibility");else value='';}else if(obj.currentStyle){value=obj.currentStyle.visibility;}else value='';}return value;};var tags=new Array("applet","iframe","select");var el=this.element;var p=Calendar.getAbsolutePos(el);var EX1=p.x;var EX2=el.offsetWidth+EX1;var EY1=p.y;var EY2=el.offsetHeight+EY1;for(var k=tags.length;k>0;){var ar=document.getElementsByTagName(tags[--k]);var cc=null;for(var i=ar.length;i>0;){cc=ar[--i];p=Calendar.getAbsolutePos(cc);var CX1=p.x;var CX2=cc.offsetWidth+CX1;var CY1=p.y;var CY2=cc.offsetHeight+CY1;if(this.hidden||(CX1>EX2)||(CX2EY2)||(CY229)?1900:2000);break;case "%b":case "%B":for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){m=j;break;}}break;case "%H":case "%I":case "%k":case "%l":hr=parseInt(a[i],10);break;case "%P":case "%p":if(/pm/i.test(a[i])&&hr<12)hr+=12;else if(/am/i.test(a[i])&&hr>=12)hr-=12;break;case "%M":min=parseInt(a[i],10);break;}}if(isNaN(y))y=today.getFullYear();if(isNaN(m))m=today.getMonth();if(isNaN(d))d=today.getDate();if(isNaN(hr))hr=today.getHours();if(isNaN(min))min=today.getMinutes();if(y!=0&&m!=-1&&d!=0)return new Date(y,m,d,hr,min,0);y=0;m=-1;d=0;for(i=0;i31&&y==0){y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);}else if(d==0){d=a[i];}}if(y==0)y=today.getFullYear();if(m!=-1&&d!=0)return new Date(y,m,d,hr,min,0);return today;};Date.prototype.getMonthDays=function(month){var year=this.getFullYear();if(typeof month=="undefined"){month=this.getMonth();}if(((0==(year%4))&&((0!=(year%100))||(0==(year%400))))&&month==1){return 29;}else{return Date._MD[month];}};Date.prototype.getDayOfYear=function(){var now=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var then=new Date(this.getFullYear(),0,0,0,0,0);var time=now-then;return Math.floor(time/Date.DAY);};Date.prototype.getWeekNumber=function(){var d=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var DoW=d.getDay();d.setDate(d.getDate()-(DoW+6)%7+3);var ms=d.valueOf();d.setMonth(0);d.setDate(4);return Math.round((ms-d.valueOf())/(7*864e5))+1;};Date.prototype.equalsTo=function(date){return((this.getFullYear()==date.getFullYear())&&(this.getMonth()==date.getMonth())&&(this.getDate()==date.getDate())&&(this.getHours()==date.getHours())&&(this.getMinutes()==date.getMinutes()));};Date.prototype.setDateOnly=function(date){var tmp=new Date(date);this.setDate(1);this.setFullYear(tmp.getFullYear());this.setMonth(tmp.getMonth());this.setDate(tmp.getDate());};Date.prototype.print=function(str){var m=this.getMonth();var d=this.getDate();var y=this.getFullYear();var wn=this.getWeekNumber();var w=this.getDay();var s={};var hr=this.getHours();var pm=(hr>=12);var ir=(pm)?(hr-12):hr;var dy=this.getDayOfYear();if(ir==0)ir=12;var min=this.getMinutes();var sec=this.getSeconds();s["%a"]=Calendar._SDN[w];s["%A"]=Calendar._DN[w];s["%b"]=Calendar._SMN[m];s["%B"]=Calendar._MN[m];s["%C"]=1+Math.floor(y/100);s["%d"]=(d<10)?("0"+d):d;s["%e"]=d;s["%H"]=(hr<10)?("0"+hr):hr;s["%I"]=(ir<10)?("0"+ir):ir;s["%j"]=(dy<100)?((dy<10)?("00"+dy):("0"+dy)):dy;s["%k"]=hr;s["%l"]=ir;s["%m"]=(m<9)?("0"+(1+m)):(1+m);s["%M"]=(min<10)?("0"+min):min;s["%n"]="\n";s["%p"]=pm?"PM":"AM";s["%P"]=pm?"pm":"am";s["%s"]=Math.floor(this.getTime()/1000);s["%S"]=(sec<10)?("0"+sec):sec;s["%t"]="\t";s["%U"]=s["%W"]=s["%V"]=(wn<10)?("0"+wn):wn;s["%u"]=w+1;s["%w"]=w;s["%y"]=(''+y).substr(2,2);s["%Y"]=y;s["%%"]="%";var re=/%./g;if(!Calendar.is_ie5&&!Calendar.is_khtml)return str.replace(re,function(par){return s[par]||par;});var a=str.match(re);for(var i=0;i= 0;) { var d = params.multiple[i]; var ds = d.print("%Y%m%d"); cal.multiple[ds] = d; } } cal.showsOtherMonths = params.showOthers; cal.yearStep = params.step; cal.setRange(params.range[0], params.range[1]); cal.params = params; cal.setDateStatusHandler(params.dateStatusFunc); cal.getDateText = params.dateText; cal.setDateFormat(dateFmt); if (mustCreate) cal.create(); cal.refresh(); if (!params.position) cal.showAtElement(params.button || params.displayArea || params.inputField, params.align); else cal.showAt(params.position[0], params.position[1]); return false; }; return cal; }; nurpawiki-1.2.3/files/jscalendar/calendar-system.css0000644000175000017500000001311310726351032023303 0ustar jhellstenjhellsten/* The main calendar widget. DIV containing a table. */ .calendar { position: relative; display: none; border: 1px solid; border-color: #fff #000 #000 #fff; font-size: 11px; cursor: default; background: Window; color: WindowText; font-family: tahoma,verdana,sans-serif; } .calendar table { border: 1px solid; border-color: #fff #000 #000 #fff; font-size: 11px; cursor: default; background: Window; color: WindowText; font-family: tahoma,verdana,sans-serif; } /* Header part -- contains navigation buttons and day names. */ .calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ text-align: center; padding: 1px; border: 1px solid; border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; background: ButtonFace; } .calendar .nav { background: ButtonFace url(menuarrow.gif) no-repeat 100% 100%; } .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; padding: 1px; border: 1px solid #000; background: ActiveCaption; color: CaptionText; text-align: center; } .calendar thead .headrow { /* Row containing navigation buttons */ } .calendar thead .daynames { /* Row containing the day names */ } .calendar thead .name { /* Cells containing the day names */ border-bottom: 1px solid ButtonShadow; padding: 2px; text-align: center; background: ButtonFace; color: ButtonText; } .calendar thead .weekend { /* How a weekend day name shows in header */ color: #f00; } .calendar thead .hilite { /* How do the buttons in header appear when hover */ border: 2px solid; padding: 0px; border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; } .calendar thead .active { /* Active (pressed) buttons in header */ border-width: 1px; padding: 2px 0px 0px 2px; border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow; } /* The body part -- contains all the days in month. */ .calendar tbody .day { /* Cells containing month days dates */ width: 2em; text-align: right; padding: 2px 4px 2px 2px; } .calendar tbody .day.othermonth { font-size: 80%; color: #aaa; } .calendar tbody .day.othermonth.oweekend { color: #faa; } .calendar table .wn { padding: 2px 3px 2px 2px; border-right: 1px solid ButtonShadow; background: ButtonFace; color: ButtonText; } .calendar tbody .rowhilite td { background: Highlight; color: HighlightText; } .calendar tbody td.hilite { /* Hovered cells */ padding: 1px 3px 1px 1px; border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; } .calendar tbody td.active { /* Active (pressed) cells */ padding: 2px 2px 0px 2px; border: 1px solid; border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow; } .calendar tbody td.selected { /* Cell showing selected date */ font-weight: bold; border: 1px solid; border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow; padding: 2px 2px 0px 2px; background: ButtonFace; color: ButtonText; } .calendar tbody td.weekend { /* Cells showing weekend days */ color: #f00; } .calendar tbody td.today { /* Cell showing today date */ font-weight: bold; color: #00f; } .calendar tbody td.disabled { color: GrayText; } .calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ visibility: hidden; } .calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ display: none; } /* The footer part -- status bar and "Close" button */ .calendar tfoot .footrow { /* The in footer (only one right now) */ } .calendar tfoot .ttip { /* Tooltip (status bar) cell */ background: ButtonFace; padding: 1px; border: 1px solid; border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow; color: ButtonText; text-align: center; } .calendar tfoot .hilite { /* Hover style for buttons in footer */ border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; padding: 1px; background: #e4e0d8; } .calendar tfoot .active { /* Active (pressed) style for buttons in footer */ padding: 2px 0px 0px 2px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; } /* Combo boxes (menus that display months/years for direct selection) */ .calendar .combo { position: absolute; display: none; width: 4em; top: 0px; left: 0px; cursor: default; border: 1px solid; border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; background: Menu; color: MenuText; font-size: 90%; padding: 1px; z-index: 100; } .calendar .combo .label, .calendar .combo .label-IEfix { text-align: center; padding: 1px; } .calendar .combo .label-IEfix { width: 4em; } .calendar .combo .active { padding: 0px; border: 1px solid #000; } .calendar .combo .hilite { background: Highlight; color: HighlightText; } .calendar td.time { border-top: 1px solid ButtonShadow; padding: 1px 0px; text-align: center; background-color: ButtonFace; } .calendar td.time .hour, .calendar td.time .minute, .calendar td.time .ampm { padding: 0px 3px 0px 4px; border: 1px solid #889; font-weight: bold; background-color: Menu; } .calendar td.time .ampm { text-align: center; } .calendar td.time .colon { padding: 0px 2px 0px 3px; font-weight: bold; } .calendar td.time span.hilite { border-color: #000; background-color: Highlight; color: HighlightText; } .calendar td.time span.active { border-color: #f00; background-color: #000; color: #0f0; } nurpawiki-1.2.3/files/jscalendar/calendar-win2k-2.css0000644000175000017500000001354210726351032023156 0ustar jhellstenjhellsten/* The main calendar widget. DIV containing a table. */ .calendar { position: relative; display: none; border-top: 2px solid #fff; border-right: 2px solid #000; border-bottom: 2px solid #000; border-left: 2px solid #fff; font-size: 11px; color: #000; cursor: default; background: #d4c8d0; font-family: tahoma,verdana,sans-serif; } .calendar table { border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; font-size: 11px; color: #000; cursor: default; background: #d4c8d0; font-family: tahoma,verdana,sans-serif; } /* Header part -- contains navigation buttons and day names. */ .calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ text-align: center; padding: 1px; border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; } .calendar .nav { background: transparent url(menuarrow.gif) no-repeat 100% 100%; } .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; padding: 1px; border: 1px solid #000; background: #847880; color: #fff; text-align: center; } .calendar thead .headrow { /* Row containing navigation buttons */ } .calendar thead .daynames { /* Row containing the day names */ } .calendar thead .name { /* Cells containing the day names */ border-bottom: 1px solid #000; padding: 2px; text-align: center; background: #f4e8f0; } .calendar thead .weekend { /* How a weekend day name shows in header */ color: #f00; } .calendar thead .hilite { /* How do the buttons in header appear when hover */ border-top: 2px solid #fff; border-right: 2px solid #000; border-bottom: 2px solid #000; border-left: 2px solid #fff; padding: 0px; background-color: #e4d8e0; } .calendar thead .active { /* Active (pressed) buttons in header */ padding: 2px 0px 0px 2px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; background-color: #c4b8c0; } /* The body part -- contains all the days in month. */ .calendar tbody .day { /* Cells containing month days dates */ width: 2em; text-align: right; padding: 2px 4px 2px 2px; } .calendar tbody .day.othermonth { font-size: 80%; color: #aaa; } .calendar tbody .day.othermonth.oweekend { color: #faa; } .calendar table .wn { padding: 2px 3px 2px 2px; border-right: 1px solid #000; background: #f4e8f0; } .calendar tbody .rowhilite td { background: #e4d8e0; } .calendar tbody .rowhilite td.wn { background: #d4c8d0; } .calendar tbody td.hilite { /* Hovered cells */ padding: 1px 3px 1px 1px; border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; } .calendar tbody td.active { /* Active (pressed) cells */ padding: 2px 2px 0px 2px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; } .calendar tbody td.selected { /* Cell showing selected date */ font-weight: bold; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; padding: 2px 2px 0px 2px; background: #e4d8e0; } .calendar tbody td.weekend { /* Cells showing weekend days */ color: #f00; } .calendar tbody td.today { /* Cell showing today date */ font-weight: bold; color: #00f; } .calendar tbody .disabled { color: #999; } .calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ visibility: hidden; } .calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ display: none; } /* The footer part -- status bar and "Close" button */ .calendar tfoot .footrow { /* The in footer (only one right now) */ } .calendar tfoot .ttip { /* Tooltip (status bar) cell */ background: #f4e8f0; padding: 1px; border: 1px solid #000; background: #847880; color: #fff; text-align: center; } .calendar tfoot .hilite { /* Hover style for buttons in footer */ border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; padding: 1px; background: #e4d8e0; } .calendar tfoot .active { /* Active (pressed) style for buttons in footer */ padding: 2px 0px 0px 2px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; } /* Combo boxes (menus that display months/years for direct selection) */ .calendar .combo { position: absolute; display: none; width: 4em; top: 0px; left: 0px; cursor: default; border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; background: #e4d8e0; font-size: 90%; padding: 1px; z-index: 100; } .calendar .combo .label, .calendar .combo .label-IEfix { text-align: center; padding: 1px; } .calendar .combo .label-IEfix { width: 4em; } .calendar .combo .active { background: #d4c8d0; padding: 0px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; } .calendar .combo .hilite { background: #408; color: #fea; } .calendar td.time { border-top: 1px solid #000; padding: 1px 0px; text-align: center; background-color: #f4f0e8; } .calendar td.time .hour, .calendar td.time .minute, .calendar td.time .ampm { padding: 0px 3px 0px 4px; border: 1px solid #889; font-weight: bold; background-color: #fff; } .calendar td.time .ampm { text-align: center; } .calendar td.time .colon { padding: 0px 2px 0px 3px; font-weight: bold; } .calendar td.time span.hilite { border-color: #000; background-color: #766; color: #fff; } .calendar td.time span.active { border-color: #f00; background-color: #000; color: #0f0; } nurpawiki-1.2.3/files/jscalendar/skins/0000755000175000017500000000000011251252513020624 5ustar jhellstenjhellstennurpawiki-1.2.3/files/jscalendar/skins/aqua/0000755000175000017500000000000011251252514021554 5ustar jhellstenjhellstennurpawiki-1.2.3/files/jscalendar/skins/aqua/normal-bg.gif0000644000175000017500000000015610726351032024124 0ustar jhellstenjhellstenGIF89aòììì÷÷÷÷ùö÷ùøøøøùùùÿÿÿ!ù!þCreated with The GIMP,ºÜñ0JC«½%ëÍ›g\¸]¤E '!¨ìº&;nurpawiki-1.2.3/files/jscalendar/skins/aqua/dark-bg.gif0000644000175000017500000000012510726351032023551 0ustar jhellstenjhellstenGIF89aÂÈÈÈÑÑÑÒÒÒÑÓÐÑÓÒÓÓÓØØØÿÿÿ!ù,ºÜñ0JC«½%ëÍ›g\¸]¤%§0¨ìº&;nurpawiki-1.2.3/files/jscalendar/skins/aqua/status-bg.gif0000644000175000017500000000016410726351032024156 0ustar jhellstenjhellstenGIF89aãyyyÛÛÛàààæææçççèèèíííîîîïïïóóóôôô÷÷÷øøøþþþÿÿÿÿÿÿ!þCreated with The GIMP,ˆPÔ ¨!bZB‹ÃLÓD;nurpawiki-1.2.3/files/jscalendar/skins/aqua/rowhover-bg.gif0000644000175000017500000000015610726351032024507 0ustar jhellstenjhellstenGIF89aÂÝÝÝèèèèéçèéèéééïïïÿÿÿÿÿÿ!þCreated with The GIMP!ù,ºÜñ0ÊB«½$ëÍ›g\¸]¤ g ¨ìº&;nurpawiki-1.2.3/files/jscalendar/skins/aqua/menuarrow.gif0000644000175000017500000000006110726351032024260 0ustar jhellstenjhellstenGIF89a€BBBÿÿÿ!ù,„yÉÀc;nurpawiki-1.2.3/files/jscalendar/skins/aqua/theme.css0000644000175000017500000001271010726351032023372 0ustar jhellstenjhellsten/* Distributed as part of The Coolest DHTML Calendar Author: Mihai Bazon, www.bazon.net/mishoo Copyright Dynarch.com 2005, www.dynarch.com */ /* The main calendar widget. DIV containing a table. */ div.calendar { position: relative; } .calendar, .calendar table { border: 1px solid #bdb2bf; font-size: 11px; color: #000; cursor: default; background: url("normal-bg.gif"); font-family: "trebuchet ms",verdana,tahoma,sans-serif; } .calendar { border-color: #797979; } /* Header part -- contains navigation buttons and day names. */ .calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ text-align: center; /* They are the navigation buttons */ padding: 2px; /* Make the buttons seem like they're pressing */ background: url("title-bg.gif") repeat-x 0 100%; color: #000; font-weight: bold; } .calendar .nav { font-family: verdana,tahoma,sans-serif; } .calendar .nav div { background: transparent url("menuarrow.gif") no-repeat 100% 100%; } .calendar thead tr { background: url("title-bg.gif") repeat-x 0 100%; color: #000; } .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; /* Pressing it will take you to the current date */ text-align: center; padding: 2px; background: url("title-bg.gif") repeat-x 0 100%; color: #000; } .calendar thead .headrow { /* Row containing navigation buttons */ } .calendar thead .name { /* Cells containing the day names */ border-bottom: 1px solid #797979; padding: 2px; text-align: center; color: #000; } .calendar thead .weekend { /* How a weekend day name shows in header */ color: #c44; } .calendar thead .hilite { /* How do the buttons in header appear when hover */ background: url("hover-bg.gif"); border-bottom: 1px solid #797979; padding: 2px 2px 1px 2px; } .calendar thead .active { /* Active (pressed) buttons in header */ background: url("active-bg.gif"); color: #fff; padding: 3px 1px 0px 3px; border-bottom: 1px solid #797979; } .calendar thead .daynames { /* Row containing the day names */ background: url("dark-bg.gif"); } /* The body part -- contains all the days in month. */ .calendar tbody .day { /* Cells containing month days dates */ font-family: verdana,tahoma,sans-serif; width: 2em; color: #000; text-align: right; padding: 2px 4px 2px 2px; } .calendar tbody .day.othermonth { font-size: 80%; color: #999; } .calendar tbody .day.othermonth.oweekend { color: #f99; } .calendar table .wn { padding: 2px 3px 2px 2px; border-right: 1px solid #797979; background: url("dark-bg.gif"); } .calendar tbody .rowhilite td, .calendar tbody .rowhilite td.wn { background: url("rowhover-bg.gif"); } .calendar tbody td.today { font-weight: bold; /* background: url("today-bg.gif") no-repeat 70% 50%; */ } .calendar tbody td.hilite { /* Hovered cells */ background: url("hover-bg.gif"); padding: 1px 3px 1px 1px; border: 1px solid #bbb; } .calendar tbody td.active { /* Active (pressed) cells */ padding: 2px 2px 0px 2px; } .calendar tbody td.weekend { /* Cells showing weekend days */ color: #c44; } .calendar tbody td.selected { /* Cell showing selected date */ font-weight: bold; border: 1px solid #797979; padding: 1px 3px 1px 1px; background: url("active-bg.gif"); color: #fff; } .calendar tbody .disabled { color: #999; } .calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ visibility: hidden; } .calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ display: none; } /* The footer part -- status bar and "Close" button */ .calendar tfoot .footrow { /* The in footer (only one right now) */ text-align: center; background: #565; color: #fff; } .calendar tfoot .ttip { /* Tooltip (status bar) cell */ padding: 2px; background: url("status-bg.gif") repeat-x 0 0; color: #000; } .calendar tfoot .hilite { /* Hover style for buttons in footer */ background: #afa; border: 1px solid #084; color: #000; padding: 1px; } .calendar tfoot .active { /* Active (pressed) style for buttons in footer */ background: #7c7; padding: 2px 0px 0px 2px; } /* Combo boxes (menus that display months/years for direct selection) */ .calendar .combo { position: absolute; display: none; top: 0px; left: 0px; width: 4em; cursor: default; border-width: 0 1px 1px 1px; border-style: solid; border-color: #797979; background: url("normal-bg.gif"); color: #000; z-index: 100; font-size: 90%; } .calendar .combo .label, .calendar .combo .label-IEfix { text-align: center; padding: 1px; } .calendar .combo .label-IEfix { width: 4em; } .calendar .combo .hilite { background: url("hover-bg.gif"); color: #000; } .calendar .combo .active { background: url("active-bg.gif"); color: #fff; font-weight: bold; } .calendar td.time { border-top: 1px solid #797979; padding: 1px 0px; text-align: center; background: url("dark-bg.gif"); } .calendar td.time .hour, .calendar td.time .minute, .calendar td.time .ampm { padding: 0px 5px 0px 6px; font-weight: bold; background: url("normal-bg.gif"); color: #000; } .calendar td.time .hour, .calendar td.time .minute { font-family: monospace; } .calendar td.time .ampm { text-align: center; } .calendar td.time .colon { padding: 0px 2px 0px 3px; font-weight: bold; } .calendar td.time span.hilite { background: url("hover-bg.gif"); color: #000; } .calendar td.time span.active { background: url("active-bg.gif"); color: #fff; } nurpawiki-1.2.3/files/jscalendar/skins/aqua/hover-bg.gif0000644000175000017500000000013110726351032023750 0ustar jhellstenjhellstenGIF89añ“©Ü™µßºá!ù!þCreated with The GIMP,„Ëí£œ®¶„‘ݳËm;nurpawiki-1.2.3/files/jscalendar/skins/aqua/title-bg.gif0000644000175000017500000000016410726351032023754 0ustar jhellstenjhellstenGIF89aãyyyÛÛÛàààæææçççèèèíííîîîïïïóóóôôô÷÷÷øøøþþþÿÿÿÿÿÿ!þCreated with The GIMP,°5v˜[(5CPCÄ D;nurpawiki-1.2.3/files/jscalendar/skins/aqua/today-bg.gif0000644000175000017500000000214210726351032023751 0ustar jhellstenjhellstenGIF89açŽþäþäþäÿäþäÿäþäþäÿäþäþäÿäþäþä ÿäþä ýä ÿäþä ÿä þä ýäþå þåþåÿåÿåþåüå"üå#þæÿæþæýæ"þæ!ûå/ûå1ýç,ýç-ùæ?ùæCýè4øæNøæSÿé0ÿé1ÿé5ÿé6ýé?üéDÿê9üéMÿêAýêHÿëCüêUüêVóèˆÿìTôèˆóè‘üìdûìgûìhÿí^òéòé ÿîbñé¤ÿîfûíwüíuûíxñé©úí€ûî€ïê¼ûî‡ÿðsîêÇûïŠîêÌîêÍúï”ÿñ~îëÏÿñíëØíëÛìëàìëâìëäùð¦ÿòŒùð¨ìëèìëëìììùñ®ùò±úò±øòºøò»ÿô úó¹ÿõ¤øóÆøóÈúôÁúôÈúôÉøôÔúõÊøôÕ÷ôØùõÒøõÚùöØ÷õä÷õå÷õæÿøÄ÷öï÷öóù÷ê÷öö÷øî÷÷÷ùøíùøòøøø÷ùö÷ùøùøøÿûÚùùùÿûàÿýîÿþöÿþøÿþüÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù ÿ,þÃH° ˜-X¶€ÉEŠ–‚"J”¸'5zúࣤŒ/?Œ¬™øÇ‘IG%RÄ(Œ -Τ¡òÁ'/2¸(ÒÅÐÉC@ ñA…L›xÀÀÀ€°!À@ Ô„Ä+ K¶,d9ðx&+€(Q¶îXIÇ PãÐI+Æfø`·n» "$ȇÓžLVŸ9 < –òäI$ÊÁAa^Ï“Ì8鑨)’¨±'‹€S0Œ ¦ËJÈ[W€ˆ|© БeÀ°PØ 9uùem d @Ø`Q÷Åè 4YKš -‚Žúû½fÙQÀ‰+U¨ÐÀ(0½‘D’)ÜðFDr Ãw(Q@;nurpawiki-1.2.3/files/jscalendar/skins/aqua/active-bg.gif0000644000175000017500000000013110726351032024100 0ustar jhellstenjhellstenGIF89añ(S¹4l¿ // Encoding: any // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"); // First day of the week. "0" means display Sunday first, "1" means display // Monday first, etc. Calendar._FD = 0; // full month names Calendar._MN = new Array ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); // short month names Calendar._SMN = new Array ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "About the calendar"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "Date selection:\n" + "- Use the \xab, \xbb buttons to select year\n" + "- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" + "- Hold mouse button on any of the above buttons for faster selection."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Time selection:\n" + "- Click on any of the time parts to increase it\n" + "- or Shift-click to decrease it\n" + "- or click and drag for faster selection."; Calendar._TT["PREV_YEAR"] = "Prev. year (hold for menu)"; Calendar._TT["PREV_MONTH"] = "Prev. month (hold for menu)"; Calendar._TT["GO_TODAY"] = "Go Today"; Calendar._TT["NEXT_MONTH"] = "Next month (hold for menu)"; Calendar._TT["NEXT_YEAR"] = "Next year (hold for menu)"; Calendar._TT["SEL_DATE"] = "Select date"; Calendar._TT["DRAG_TO_MOVE"] = "Drag to move"; Calendar._TT["PART_TODAY"] = " (today)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Display %s first"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Close"; Calendar._TT["TODAY"] = "Today"; Calendar._TT["TIME_PART"] = "(Shift-)Click or drag to change value"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["WK"] = "wk"; Calendar._TT["TIME"] = "Time:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-jp.js0000644000175000017500000000162110726351032023136 0ustar jhellstenjhellsten// ** I18N Calendar._DN = new Array ("“ú", "ŒŽ", "‰Î", "…", "–Ø", "‹à", "“y", "“ú"); Calendar._MN = new Array ("1ŒŽ", "2ŒŽ", "3ŒŽ", "4ŒŽ", "5ŒŽ", "6ŒŽ", "7ŒŽ", "8ŒŽ", "9ŒŽ", "10ŒŽ", "11ŒŽ", "12ŒŽ"); // tooltips Calendar._TT = {}; Calendar._TT["TOGGLE"] = "T‚Ìʼn‚Ì—j“ú‚ðØ‚è‘Ö‚¦"; Calendar._TT["PREV_YEAR"] = "‘O”N"; Calendar._TT["PREV_MONTH"] = "‘OŒŽ"; Calendar._TT["GO_TODAY"] = "¡“ú"; Calendar._TT["NEXT_MONTH"] = "—‚ŒŽ"; Calendar._TT["NEXT_YEAR"] = "—‚”N"; Calendar._TT["SEL_DATE"] = "“ú•t‘I‘ð"; Calendar._TT["DRAG_TO_MOVE"] = "ƒEƒBƒ“ƒhƒE‚̈ړ®"; Calendar._TT["PART_TODAY"] = " (¡“ú)"; Calendar._TT["MON_FIRST"] = "ŒŽ—j“ú‚ðæ“ª‚É"; Calendar._TT["SUN_FIRST"] = "“ú—j“ú‚ðæ“ª‚É"; Calendar._TT["CLOSE"] = "•‚¶‚é"; Calendar._TT["TODAY"] = "¡“ú"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "y-mm-dd"; Calendar._TT["TT_DATE_FORMAT"] = "%mŒŽ %d“ú (%a)"; Calendar._TT["WK"] = "T"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-cs-win.js0000644000175000017500000000522110726351032023725 0ustar jhellstenjhellsten/* calendar-cs-win.js language: Czech encoding: windows-1250 author: Lubos Jerabek (xnet@seznam.cz) Jan Uhlir (espinosa@centrum.cz) */ // ** I18N Calendar._DN = new Array('Nedìle','Pondìlí','Úterý','Støeda','Ètvrtek','Pátek','Sobota','Nedìle'); Calendar._SDN = new Array('Ne','Po','Út','St','Èt','Pá','So','Ne'); Calendar._MN = new Array('Leden','Únor','Bøezen','Duben','Kvìten','Èerven','Èervenec','Srpen','Záøí','Øíjen','Listopad','Prosinec'); Calendar._SMN = new Array('Led','Úno','Bøe','Dub','Kvì','Èrv','Èvc','Srp','Záø','Øíj','Lis','Pro'); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "O komponentì kalendáø"; Calendar._TT["TOGGLE"] = "Zmìna prvního dne v týdnu"; Calendar._TT["PREV_YEAR"] = "Pøedchozí rok (pøidrž pro menu)"; Calendar._TT["PREV_MONTH"] = "Pøedchozí mìsíc (pøidrž pro menu)"; Calendar._TT["GO_TODAY"] = "Dnešní datum"; Calendar._TT["NEXT_MONTH"] = "Další mìsíc (pøidrž pro menu)"; Calendar._TT["NEXT_YEAR"] = "Další rok (pøidrž pro menu)"; Calendar._TT["SEL_DATE"] = "Vyber datum"; Calendar._TT["DRAG_TO_MOVE"] = "Chy a táhni, pro pøesun"; Calendar._TT["PART_TODAY"] = " (dnes)"; Calendar._TT["MON_FIRST"] = "Ukaž jako první Pondìlí"; //Calendar._TT["SUN_FIRST"] = "Ukaž jako první Nedìli"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "Výbìr datumu:\n" + "- Use the \xab, \xbb buttons to select year\n" + "- Použijte tlaèítka " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " k výbìru mìsíce\n" + "- Podržte tlaèítko myši na jakémkoliv z tìch tlaèítek pro rychlejší výbìr."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Výbìr èasu:\n" + "- Kliknìte na jakoukoliv z èástí výbìru èasu pro zvýšení.\n" + "- nebo Shift-click pro snížení\n" + "- nebo kliknìte a táhnìte pro rychlejší výbìr."; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Zobraz %s první"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Zavøít"; Calendar._TT["TODAY"] = "Dnes"; Calendar._TT["TIME_PART"] = "(Shift-)Klikni nebo táhni pro zmìnu hodnoty"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "d.m.yy"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["WK"] = "wk"; Calendar._TT["TIME"] = "Èas:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-da.js0000644000175000017500000000665410726351032023124 0ustar jhellstenjhellsten// ** I18N // Calendar DA language // Author: Michael Thingmand Henriksen, // Encoding: any // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag", "Søndag"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør", "Søn"); // full month names Calendar._MN = new Array ("Januar", "Februar", "Marts", "April", "Maj", "Juni", "Juli", "August", "September", "Oktober", "November", "December"); // short month names Calendar._SMN = new Array ("Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Om Kalenderen"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For den seneste version besøg: http://www.dynarch.com/projects/calendar/\n"; + "Distribueret under GNU LGPL. Se http://gnu.org/licenses/lgpl.html for detajler." + "\n\n" + "Valg af dato:\n" + "- Brug \xab, \xbb knapperne for at vælge Ã¥r\n" + "- Brug " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " knapperne for at vælge mÃ¥ned\n" + "- Hold knappen pÃ¥ musen nede pÃ¥ knapperne ovenfor for hurtigere valg."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Valg af tid:\n" + "- Klik pÃ¥ en vilkÃ¥rlig del for større værdi\n" + "- eller Shift-klik for for mindre værdi\n" + "- eller klik og træk for hurtigere valg."; Calendar._TT["PREV_YEAR"] = "Ét Ã¥r tilbage (hold for menu)"; Calendar._TT["PREV_MONTH"] = "Én mÃ¥ned tilbage (hold for menu)"; Calendar._TT["GO_TODAY"] = "GÃ¥ til i dag"; Calendar._TT["NEXT_MONTH"] = "Én mÃ¥ned frem (hold for menu)"; Calendar._TT["NEXT_YEAR"] = "Ét Ã¥r frem (hold for menu)"; Calendar._TT["SEL_DATE"] = "Vælg dag"; Calendar._TT["DRAG_TO_MOVE"] = "Træk vinduet"; Calendar._TT["PART_TODAY"] = " (i dag)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Vis %s først"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Luk"; Calendar._TT["TODAY"] = "I dag"; Calendar._TT["TIME_PART"] = "(Shift-)klik eller træk for at ændre værdi"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["WK"] = "Uge"; Calendar._TT["TIME"] = "Tid:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-it.js0000644000175000017500000000706110726351032023145 0ustar jhellstenjhellsten// ** I18N // Calendar EN language // Author: Mihai Bazon, // Translator: Fabio Di Bernardini, // Encoding: any // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato", "Domenica"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab", "Dom"); // full month names Calendar._MN = new Array ("Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Augosto", "Settembre", "Ottobre", "Novembre", "Dicembre"); // short month names Calendar._SMN = new Array ("Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Informazioni sul calendario"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "Per gli aggiornamenti: http://www.dynarch.com/projects/calendar/\n" + "Distribuito sotto licenza GNU LGPL. Vedi http://gnu.org/licenses/lgpl.html per i dettagli." + "\n\n" + "Selezione data:\n" + "- Usa \xab, \xbb per selezionare l'anno\n" + "- Usa " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " per i mesi\n" + "- Tieni premuto a lungo il mouse per accedere alle funzioni di selezione veloce."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Selezione orario:\n" + "- Clicca sul numero per incrementarlo\n" + "- o Shift+click per decrementarlo\n" + "- o click e sinistra o destra per variarlo."; Calendar._TT["PREV_YEAR"] = "Anno prec.(clicca a lungo per il menù)"; Calendar._TT["PREV_MONTH"] = "Mese prec. (clicca a lungo per il menù)"; Calendar._TT["GO_TODAY"] = "Oggi"; Calendar._TT["NEXT_MONTH"] = "Pross. mese (clicca a lungo per il menù)"; Calendar._TT["NEXT_YEAR"] = "Pross. anno (clicca a lungo per il menù)"; Calendar._TT["SEL_DATE"] = "Seleziona data"; Calendar._TT["DRAG_TO_MOVE"] = "Trascina per spostarlo"; Calendar._TT["PART_TODAY"] = " (oggi)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Mostra prima %s"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Chiudi"; Calendar._TT["TODAY"] = "Oggi"; Calendar._TT["TIME_PART"] = "(Shift-)Click o trascina per cambiare il valore"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y"; Calendar._TT["TT_DATE_FORMAT"] = "%a:%b:%e"; Calendar._TT["WK"] = "set"; Calendar._TT["TIME"] = "Ora:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-ro.js0000644000175000017500000000401210726351032023142 0ustar jhellstenjhellsten// ** I18N Calendar._DN = new Array ("Duminică", "Luni", "MarÅ£i", "Miercuri", "Joi", "Vineri", "Sâmbătă", "Duminică"); Calendar._SDN_len = 2; Calendar._MN = new Array ("Ianuarie", "Februarie", "Martie", "Aprilie", "Mai", "Iunie", "Iulie", "August", "Septembrie", "Octombrie", "Noiembrie", "Decembrie"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Despre calendar"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "Pentru ultima versiune vizitaÅ£i: http://www.dynarch.com/projects/calendar/\n" + "Distribuit sub GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "SelecÅ£ia datei:\n" + "- FolosiÅ£i butoanele \xab, \xbb pentru a selecta anul\n" + "- FolosiÅ£i butoanele " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " pentru a selecta luna\n" + "- TineÅ£i butonul mouse-ului apăsat pentru selecÅ£ie mai rapidă."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "SelecÅ£ia orei:\n" + "- Click pe ora sau minut pentru a mări valoarea cu 1\n" + "- Sau Shift-Click pentru a micÅŸora valoarea cu 1\n" + "- Sau Click ÅŸi drag pentru a selecta mai repede."; Calendar._TT["PREV_YEAR"] = "Anul precedent (lung pt menu)"; Calendar._TT["PREV_MONTH"] = "Luna precedentă (lung pt menu)"; Calendar._TT["GO_TODAY"] = "Data de azi"; Calendar._TT["NEXT_MONTH"] = "Luna următoare (lung pt menu)"; Calendar._TT["NEXT_YEAR"] = "Anul următor (lung pt menu)"; Calendar._TT["SEL_DATE"] = "Selectează data"; Calendar._TT["DRAG_TO_MOVE"] = "Trage pentru a miÅŸca"; Calendar._TT["PART_TODAY"] = " (astăzi)"; Calendar._TT["DAY_FIRST"] = "AfiÅŸează %s prima zi"; Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "ÃŽnchide"; Calendar._TT["TODAY"] = "Astăzi"; Calendar._TT["TIME_PART"] = "(Shift-)Click sau drag pentru a selecta"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y"; Calendar._TT["TT_DATE_FORMAT"] = "%A, %d %B"; Calendar._TT["WK"] = "spt"; Calendar._TT["TIME"] = "Ora:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-es.js0000644000175000017500000000751510726351032023144 0ustar jhellstenjhellsten// ** I18N // Calendar ES (spanish) language // Author: Mihai Bazon, // Updater: Servilio Afre Puentes // Updated: 2004-06-03 // Encoding: utf-8 // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb", "Dom"); // First day of the week. "0" means display Sunday first, "1" means display // Monday first, etc. Calendar._FD = 1; // full month names Calendar._MN = new Array ("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"); // short month names Calendar._SMN = new Array ("Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Acerca del calendario"; Calendar._TT["ABOUT"] = "Selector DHTML de Fecha/Hora\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "Para conseguir la última versión visite: http://www.dynarch.com/projects/calendar/\n" + "Distribuido bajo licencia GNU LGPL. Visite http://gnu.org/licenses/lgpl.html para más detalles." + "\n\n" + "Selección de fecha:\n" + "- Use los botones \xab, \xbb para seleccionar el año\n" + "- Use los botones " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para seleccionar el mes\n" + "- Mantenga pulsado el ratón en cualquiera de estos botones para una selección rápida."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Selección de hora:\n" + "- Pulse en cualquiera de las partes de la hora para incrementarla\n" + "- o pulse las mayúsculas mientras hace clic para decrementarla\n" + "- o haga clic y arrastre el ratón para una selección más rápida."; Calendar._TT["PREV_YEAR"] = "Año anterior (mantener para menú)"; Calendar._TT["PREV_MONTH"] = "Mes anterior (mantener para menú)"; Calendar._TT["GO_TODAY"] = "Ir a hoy"; Calendar._TT["NEXT_MONTH"] = "Mes siguiente (mantener para menú)"; Calendar._TT["NEXT_YEAR"] = "Año siguiente (mantener para menú)"; Calendar._TT["SEL_DATE"] = "Seleccionar fecha"; Calendar._TT["DRAG_TO_MOVE"] = "Arrastrar para mover"; Calendar._TT["PART_TODAY"] = " (hoy)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Hacer %s primer día de la semana"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Cerrar"; Calendar._TT["TODAY"] = "Hoy"; Calendar._TT["TIME_PART"] = "(Mayúscula-)Clic o arrastre para cambiar valor"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y"; Calendar._TT["TT_DATE_FORMAT"] = "%A, %e de %B de %Y"; Calendar._TT["WK"] = "sem"; Calendar._TT["TIME"] = "Hora:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-ru_win_.js0000644000175000017500000000707310726351032024176 0ustar jhellstenjhellsten// ** I18N // Calendar RU language // Translation: Sly Golovanov, http://golovanov.net, // Encoding: any // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("âîñêðåñåíüå", "ïîíåäåëüíèê", "âòîðíèê", "ñðåäà", "÷åòâåðã", "ïÿòíèöà", "ñóááîòà", "âîñêðåñåíüå"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("âñê", "ïîí", "âòð", "ñðä", "÷åò", "ïÿò", "ñóá", "âñê"); // full month names Calendar._MN = new Array ("ÿíâàðü", "ôåâðàëü", "ìàðò", "àïðåëü", "ìàé", "èþíü", "èþëü", "àâãóñò", "ñåíòÿáðü", "îêòÿáðü", "íîÿáðü", "äåêàáðü"); // short month names Calendar._SMN = new Array ("ÿíâ", "ôåâ", "ìàð", "àïð", "ìàé", "èþí", "èþë", "àâã", "ñåí", "îêò", "íîÿ", "äåê"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Î êàëåíäàðå..."; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "Êàê âûáðàòü äàòó:\n" + "- Ïðè ïîìîùè êíîïîê \xab, \xbb ìîæíî âûáðàòü ãîä\n" + "- Ïðè ïîìîùè êíîïîê " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " ìîæíî âûáðàòü ìåñÿö\n" + "- Ïîäåðæèòå ýòè êíîïêè íàæàòûìè, ÷òîáû ïîÿâèëîñü ìåíþ áûñòðîãî âûáîðà."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Êàê âûáðàòü âðåìÿ:\n" + "- Ïðè êëèêå íà ÷àñàõ èëè ìèíóòàõ îíè óâåëè÷èâàþòñÿ\n" + "- ïðè êëèêå ñ íàæàòîé êëàâèøåé Shift îíè óìåíüøàþòñÿ\n" + "- åñëè íàæàòü è äâèãàòü ìûøêîé âëåâî/âïðàâî, îíè áóäóò ìåíÿòüñÿ áûñòðåå."; Calendar._TT["PREV_YEAR"] = "Íà ãîä íàçàä (óäåðæèâàòü äëÿ ìåíþ)"; Calendar._TT["PREV_MONTH"] = "Íà ìåñÿö íàçàä (óäåðæèâàòü äëÿ ìåíþ)"; Calendar._TT["GO_TODAY"] = "Ñåãîäíÿ"; Calendar._TT["NEXT_MONTH"] = "Íà ìåñÿö âïåðåä (óäåðæèâàòü äëÿ ìåíþ)"; Calendar._TT["NEXT_YEAR"] = "Íà ãîä âïåðåä (óäåðæèâàòü äëÿ ìåíþ)"; Calendar._TT["SEL_DATE"] = "Âûáåðèòå äàòó"; Calendar._TT["DRAG_TO_MOVE"] = "Ïåðåòàñêèâàéòå ìûøêîé"; Calendar._TT["PART_TODAY"] = " (ñåãîäíÿ)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Ïåðâûé äåíü íåäåëè áóäåò %s"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Çàêðûòü"; Calendar._TT["TODAY"] = "Ñåãîäíÿ"; Calendar._TT["TIME_PART"] = "(Shift-)êëèê èëè íàæàòü è äâèãàòü"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%e %b, %a"; Calendar._TT["WK"] = "íåä"; Calendar._TT["TIME"] = "Âðåìÿ:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-lt-utf8.js0000644000175000017500000000655010726351032024036 0ustar jhellstenjhellsten// ** I18N // Calendar LT language // Author: Martynas Majeris, // Encoding: UTF-8 // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Sekmadienis", "Pirmadienis", "Antradienis", "TreÄiadienis", "Ketvirtadienis", "Pentadienis", "Å eÅ¡tadienis", "Sekmadienis"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("Sek", "Pir", "Ant", "Tre", "Ket", "Pen", "Å eÅ¡", "Sek"); // full month names Calendar._MN = new Array ("Sausis", "Vasaris", "Kovas", "Balandis", "Gegužė", "Birželis", "Liepa", "RugpjÅ«tis", "RugsÄ—jis", "Spalis", "Lapkritis", "Gruodis"); // short month names Calendar._SMN = new Array ("Sau", "Vas", "Kov", "Bal", "Geg", "Bir", "Lie", "Rgp", "Rgs", "Spa", "Lap", "Gru"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Apie kalendorių"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "NaujausiÄ… versijÄ… rasite: http://www.dynarch.com/projects/calendar/\n" + "Platinamas pagal GNU LGPL licencijÄ…. Aplankykite http://gnu.org/licenses/lgpl.html" + "\n\n" + "Datos pasirinkimas:\n" + "- Metų pasirinkimas: \xab, \xbb\n" + "- MÄ—nesio pasirinkimas: " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "\n" + "- Nuspauskite ir laikykite pelÄ—s klavišą greitesniam pasirinkimui."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Laiko pasirinkimas:\n" + "- Spustelkite ant valandų arba minuÄių - skaiÄius padidÄ—s vienetu.\n" + "- Jei spausite kartu su Shift, skaiÄius sumažės.\n" + "- Greitam pasirinkimui spustelkite ir pajudinkite pelÄ™."; Calendar._TT["PREV_YEAR"] = "Ankstesni metai (laikykite, jei norite meniu)"; Calendar._TT["PREV_MONTH"] = "Ankstesnis mÄ—nuo (laikykite, jei norite meniu)"; Calendar._TT["GO_TODAY"] = "Pasirinkti Å¡iandienÄ…"; Calendar._TT["NEXT_MONTH"] = "Kitas mÄ—nuo (laikykite, jei norite meniu)"; Calendar._TT["NEXT_YEAR"] = "Kiti metai (laikykite, jei norite meniu)"; Calendar._TT["SEL_DATE"] = "Pasirinkite datÄ…"; Calendar._TT["DRAG_TO_MOVE"] = "Tempkite"; Calendar._TT["PART_TODAY"] = " (Å¡iandien)"; Calendar._TT["MON_FIRST"] = "Pirma savaitÄ—s diena - pirmadienis"; Calendar._TT["SUN_FIRST"] = "Pirma savaitÄ—s diena - sekmadienis"; Calendar._TT["CLOSE"] = "Uždaryti"; Calendar._TT["TODAY"] = "Å iandien"; Calendar._TT["TIME_PART"] = "Spustelkite arba tempkite jei norite pakeisti"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%A, %Y-%m-%d"; Calendar._TT["WK"] = "sav"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-ca.js0000644000175000017500000000701510726351032023113 0ustar jhellstenjhellsten// ** I18N // Calendar CA language // Author: Mihai Bazon, // Encoding: any // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Diumenge", "Dilluns", "Dimarts", "Dimecres", "Dijous", "Divendres", "Dissabte", "Diumenge"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("Diu", "Dil", "Dmt", "Dmc", "Dij", "Div", "Dis", "Diu"); // full month names Calendar._MN = new Array ("Gener", "Febrer", "Març", "Abril", "Maig", "Juny", "Juliol", "Agost", "Setembre", "Octubre", "Novembre", "Desembre"); // short month names Calendar._SMN = new Array ("Gen", "Feb", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Oct", "Nov", "Des"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Sobre el calendari"; Calendar._TT["ABOUT"] = "DHTML Selector de Data/Hora\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "Sel.lecció de Dates:\n" + "- Fes servir els botons \xab, \xbb per sel.leccionar l'any\n" + "- Fes servir els botons " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " per se.lecciconar el mes\n" + "- Manté el ratolí apretat en qualsevol dels anteriors per sel.lecció ràpida."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Time selection:\n" + "- claca en qualsevol de les parts de la hora per augmentar-les\n" + "- o Shift-click per decrementar-la\n" + "- or click and arrastra per sel.lecció ràpida."; Calendar._TT["PREV_YEAR"] = "Any anterior (Mantenir per menu)"; Calendar._TT["PREV_MONTH"] = "Mes anterior (Mantenir per menu)"; Calendar._TT["GO_TODAY"] = "Anar a avui"; Calendar._TT["NEXT_MONTH"] = "Mes següent (Mantenir per menu)"; Calendar._TT["NEXT_YEAR"] = "Any següent (Mantenir per menu)"; Calendar._TT["SEL_DATE"] = "Sel.leccionar data"; Calendar._TT["DRAG_TO_MOVE"] = "Arrastrar per moure"; Calendar._TT["PART_TODAY"] = " (avui)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Mostra %s primer"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Tanca"; Calendar._TT["TODAY"] = "Avui"; Calendar._TT["TIME_PART"] = "(Shift-)Click a arrastra per canviar el valor"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["WK"] = "st"; Calendar._TT["TIME"] = "Hora:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-br.js0000644000175000017500000000717210726351032023137 0ustar jhellstenjhellsten// ** I18N // Calendar pt-BR language // Author: Fernando Dourado, // Encoding: any // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sabádo", "Domingo"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names // [No changes using default values] // full month names Calendar._MN = new Array ("Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"); // short month names // [No changes using default values] // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Sobre o calendário"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "Translate to portuguese Brazil (pt-BR) by Fernando Dourado (fernando.dourado@ig.com.br)\n" + "Tradução para o português Brasil (pt-BR) por Fernando Dourado (fernando.dourado@ig.com.br)" + "\n\n" + "Selecionar data:\n" + "- Use as teclas \xab, \xbb para selecionar o ano\n" + "- Use as teclas " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para selecionar o mês\n" + "- Clique e segure com o mouse em qualquer botão para selecionar rapidamente."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Selecionar hora:\n" + "- Clique em qualquer uma das partes da hora para aumentar\n" + "- ou Shift-clique para diminuir\n" + "- ou clique e arraste para selecionar rapidamente."; Calendar._TT["PREV_YEAR"] = "Ano anterior (clique e segure para menu)"; Calendar._TT["PREV_MONTH"] = "Mês anterior (clique e segure para menu)"; Calendar._TT["GO_TODAY"] = "Ir para a data atual"; Calendar._TT["NEXT_MONTH"] = "Próximo mês (clique e segure para menu)"; Calendar._TT["NEXT_YEAR"] = "Próximo ano (clique e segure para menu)"; Calendar._TT["SEL_DATE"] = "Selecione uma data"; Calendar._TT["DRAG_TO_MOVE"] = "Clique e segure para mover"; Calendar._TT["PART_TODAY"] = " (hoje)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Exibir %s primeiro"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Fechar"; Calendar._TT["TODAY"] = "Hoje"; Calendar._TT["TIME_PART"] = "(Shift-)Clique ou arraste para mudar o valor"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y"; Calendar._TT["TT_DATE_FORMAT"] = "%d de %B de %Y"; Calendar._TT["WK"] = "sem"; Calendar._TT["TIME"] = "Hora:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-lv.js0000644000175000017500000000702310726351032023150 0ustar jhellstenjhellsten// ** I18N // Calendar LV language // Author: Juris Valdovskis, // Encoding: cp1257 // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Svçtdiena", "Pirmdiena", "Otrdiena", "Treðdiena", "Ceturdiena", "Piektdiena", "Sestdiena", "Svçtdiena"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("Sv", "Pr", "Ot", "Tr", "Ce", "Pk", "Se", "Sv"); // full month names Calendar._MN = new Array ("Janvâris", "Februâris", "Marts", "Aprîlis", "Maijs", "Jûnijs", "Jûlijs", "Augusts", "Septembris", "Oktobris", "Novembris", "Decembris"); // short month names Calendar._SMN = new Array ("Jan", "Feb", "Mar", "Apr", "Mai", "Jûn", "Jûl", "Aug", "Sep", "Okt", "Nov", "Dec"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Par kalendâru"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "Datuma izvçle:\n" + "- Izmanto \xab, \xbb pogas, lai izvçlçtos gadu\n" + "- Izmanto " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "pogas, lai izvçlçtos mçnesi\n" + "- Turi nospiestu peles pogu uz jebkuru no augstâk minçtajâm pogâm, lai paâtrinâtu izvçli."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Laika izvçle:\n" + "- Uzklikðíini uz jebkuru no laika daïâm, lai palielinâtu to\n" + "- vai Shift-klikðíis, lai samazinâtu to\n" + "- vai noklikðíini un velc uz attiecîgo virzienu lai mainîtu âtrâk."; Calendar._TT["PREV_YEAR"] = "Iepr. gads (turi izvçlnei)"; Calendar._TT["PREV_MONTH"] = "Iepr. mçnesis (turi izvçlnei)"; Calendar._TT["GO_TODAY"] = "Ðodien"; Calendar._TT["NEXT_MONTH"] = "Nâkoðais mçnesis (turi izvçlnei)"; Calendar._TT["NEXT_YEAR"] = "Nâkoðais gads (turi izvçlnei)"; Calendar._TT["SEL_DATE"] = "Izvçlies datumu"; Calendar._TT["DRAG_TO_MOVE"] = "Velc, lai pârvietotu"; Calendar._TT["PART_TODAY"] = " (ðodien)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Attçlot %s kâ pirmo"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "1,7"; Calendar._TT["CLOSE"] = "Aizvçrt"; Calendar._TT["TODAY"] = "Ðodien"; Calendar._TT["TIME_PART"] = "(Shift-)Klikðíis vai pârvieto, lai mainîtu"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %e %b"; Calendar._TT["WK"] = "wk"; Calendar._TT["TIME"] = "Laiks:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-hr.js0000644000175000017500000000602010726351032023134 0ustar jhellstenjhellstenÿþ/* Croatian language file for the DHTML Calendar version 0.9.2 * Author Krunoslav Zubrinic <krunoslav.zubrinic@vip.hr>, June 2003. * Feel free to use this script under the terms of the GNU Lesser General * Public License, as long as you do not remove or alter this notice. */ Calendar._DN = new Array ("Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", " etvrtak", "Petak", "Subota", "Nedjelja"); Calendar._MN = new Array ("Sije anj", "Velja a", "O~ujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"); // tooltips Calendar._TT = {}; Calendar._TT["TOGGLE"] = "Promjeni dan s kojim po inje tjedan"; Calendar._TT["PREV_YEAR"] = "Prethodna godina (dugi pritisak za meni)"; Calendar._TT["PREV_MONTH"] = "Prethodni mjesec (dugi pritisak za meni)"; Calendar._TT["GO_TODAY"] = "Idi na tekui dan"; Calendar._TT["NEXT_MONTH"] = "Slijedei mjesec (dugi pritisak za meni)"; Calendar._TT["NEXT_YEAR"] = "Slijedea godina (dugi pritisak za meni)"; Calendar._TT["SEL_DATE"] = "Izaberite datum"; Calendar._TT["DRAG_TO_MOVE"] = "Pritisni i povuci za promjenu pozicije"; Calendar._TT["PART_TODAY"] = " (today)"; Calendar._TT["MON_FIRST"] = "Prika~i ponedjeljak kao prvi dan"; Calendar._TT["SUN_FIRST"] = "Prika~i nedjelju kao prvi dan"; Calendar._TT["CLOSE"] = "Zatvori"; Calendar._TT["TODAY"] = "Danas"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "dd-mm-y"; Calendar._TT["TT_DATE_FORMAT"] = "DD, dd.mm.y"; Calendar._TT["WK"] = "Tje";nurpawiki-1.2.3/files/jscalendar/lang/calendar-ko.js0000644000175000017500000000627010726351032023143 0ustar jhellstenjhellsten// ** I18N // Calendar EN language // Author: Mihai Bazon, // Translation: Yourim Yi // Encoding: EUC-KR // lang : ko // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("ÀÏ¿äÀÏ", "¿ù¿äÀÏ", "È­¿äÀÏ", "¼ö¿äÀÏ", "¸ñ¿äÀÏ", "±Ý¿äÀÏ", "Åä¿äÀÏ", "ÀÏ¿äÀÏ"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("ÀÏ", "¿ù", "È­", "¼ö", "¸ñ", "±Ý", "Åä", "ÀÏ"); // full month names Calendar._MN = new Array ("1¿ù", "2¿ù", "3¿ù", "4¿ù", "5¿ù", "6¿ù", "7¿ù", "8¿ù", "9¿ù", "10¿ù", "11¿ù", "12¿ù"); // short month names Calendar._SMN = new Array ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "calendar ¿¡ ´ëÇØ¼­"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "\n"+ "ÃֽйöÀüÀ» ¹ÞÀ¸½Ã·Á¸é http://www.dynarch.com/projects/calendar/ ¿¡ ¹æ¹®Çϼ¼¿ä\n" + "\n"+ "GNU LGPL ¶óÀ̼¾½º·Î ¹èÆ÷µË´Ï´Ù. \n"+ "¶óÀ̼¾½º¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ³»¿ëÀº http://gnu.org/licenses/lgpl.html À» ÀÐÀ¸¼¼¿ä." + "\n\n" + "³¯Â¥ ¼±ÅÃ:\n" + "- ¿¬µµ¸¦ ¼±ÅÃÇÏ·Á¸é \xab, \xbb ¹öưÀ» »ç¿ëÇÕ´Ï´Ù\n" + "- ´ÞÀ» ¼±ÅÃÇÏ·Á¸é " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " ¹öưÀ» ´©¸£¼¼¿ä\n" + "- °è¼Ó ´©¸£°í ÀÖÀ¸¸é À§ °ªµéÀ» ºü¸£°Ô ¼±ÅÃÇÏ½Ç ¼ö ÀÖ½À´Ï´Ù."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "½Ã°£ ¼±ÅÃ:\n" + "- ¸¶¿ì½º·Î ´©¸£¸é ½Ã°£ÀÌ Áõ°¡ÇÕ´Ï´Ù\n" + "- Shift Ű¿Í ÇÔ²² ´©¸£¸é °¨¼ÒÇÕ´Ï´Ù\n" + "- ´©¸¥ »óÅ¿¡¼­ ¸¶¿ì½º¸¦ ¿òÁ÷À̸é Á» ´õ ºü¸£°Ô °ªÀÌ º¯ÇÕ´Ï´Ù.\n"; Calendar._TT["PREV_YEAR"] = "Áö³­ ÇØ (±æ°Ô ´©¸£¸é ¸ñ·Ï)"; Calendar._TT["PREV_MONTH"] = "Áö³­ ´Þ (±æ°Ô ´©¸£¸é ¸ñ·Ï)"; Calendar._TT["GO_TODAY"] = "¿À´Ã ³¯Â¥·Î"; Calendar._TT["NEXT_MONTH"] = "´ÙÀ½ ´Þ (±æ°Ô ´©¸£¸é ¸ñ·Ï)"; Calendar._TT["NEXT_YEAR"] = "´ÙÀ½ ÇØ (±æ°Ô ´©¸£¸é ¸ñ·Ï)"; Calendar._TT["SEL_DATE"] = "³¯Â¥¸¦ ¼±ÅÃÇϼ¼¿ä"; Calendar._TT["DRAG_TO_MOVE"] = "¸¶¿ì½º µå·¡±×·Î À̵¿ Çϼ¼¿ä"; Calendar._TT["PART_TODAY"] = " (¿À´Ã)"; Calendar._TT["MON_FIRST"] = "¿ù¿äÀÏÀ» ÇÑ ÁÖÀÇ ½ÃÀÛ ¿äÀÏ·Î"; Calendar._TT["SUN_FIRST"] = "ÀÏ¿äÀÏÀ» ÇÑ ÁÖÀÇ ½ÃÀÛ ¿äÀÏ·Î"; Calendar._TT["CLOSE"] = "´Ý±â"; Calendar._TT["TODAY"] = "¿À´Ã"; Calendar._TT["TIME_PART"] = "(Shift-)Ŭ¸¯ ¶Ç´Â µå·¡±× Çϼ¼¿ä"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%b/%e [%a]"; Calendar._TT["WK"] = "ÁÖ"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-big5.js0000644000175000017500000000633210726351032023357 0ustar jhellstenjhellsten// ** I18N // Calendar big5 language // Author: Gary Fu, // Encoding: big5 // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("¬P´Á¤é", "¬P´Á¤@", "¬P´Á¤G", "¬P´Á¤T", "¬P´Á¥|", "¬P´Á¤­", "¬P´Á¤»", "¬P´Á¤é"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("¤é", "¤@", "¤G", "¤T", "¥|", "¤­", "¤»", "¤é"); // full month names Calendar._MN = new Array ("¤@¤ë", "¤G¤ë", "¤T¤ë", "¥|¤ë", "¤­¤ë", "¤»¤ë", "¤C¤ë", "¤K¤ë", "¤E¤ë", "¤Q¤ë", "¤Q¤@¤ë", "¤Q¤G¤ë"); // short month names Calendar._SMN = new Array ("¤@¤ë", "¤G¤ë", "¤T¤ë", "¥|¤ë", "¤­¤ë", "¤»¤ë", "¤C¤ë", "¤K¤ë", "¤E¤ë", "¤Q¤ë", "¤Q¤@¤ë", "¤Q¤G¤ë"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Ãö©ó"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "¤é´Á¿ï¾Ü¤èªk:\n" + "- ¨Ï¥Î \xab, \xbb «ö¶s¥i¿ï¾Ü¦~¥÷\n" + "- ¨Ï¥Î " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " «ö¶s¥i¿ï¾Ü¤ë¥÷\n" + "- «ö¦í¤W­±ªº«ö¶s¥i¥H¥[§Ö¿ï¨ú"; Calendar._TT["ABOUT_TIME"] = "\n\n" + "®É¶¡¿ï¾Ü¤èªk:\n" + "- ÂIÀ»¥ô¦óªº®É¶¡³¡¥÷¥i¼W¥[¨ä­È\n" + "- ¦P®É«öShiftÁä¦AÂIÀ»¥i´î¤Ö¨ä­È\n" + "- ÂIÀ»¨Ã©ì¦²¥i¥[§Ö§ïÅܪº­È"; Calendar._TT["PREV_YEAR"] = "¤W¤@¦~ («ö¦í¿ï³æ)"; Calendar._TT["PREV_MONTH"] = "¤U¤@¦~ («ö¦í¿ï³æ)"; Calendar._TT["GO_TODAY"] = "¨ì¤µ¤é"; Calendar._TT["NEXT_MONTH"] = "¤W¤@¤ë («ö¦í¿ï³æ)"; Calendar._TT["NEXT_YEAR"] = "¤U¤@¤ë («ö¦í¿ï³æ)"; Calendar._TT["SEL_DATE"] = "¿ï¾Ü¤é´Á"; Calendar._TT["DRAG_TO_MOVE"] = "©ì¦²"; Calendar._TT["PART_TODAY"] = " (¤µ¤é)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "±N %s Åã¥Ü¦b«e"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Ãö³¬"; Calendar._TT["TODAY"] = "¤µ¤é"; Calendar._TT["TIME_PART"] = "ÂIÀ»or©ì¦²¥i§ïÅܮɶ¡(¦P®É«öShift¬°´î)"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["WK"] = "¶g"; Calendar._TT["TIME"] = "Time:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-sv.js0000644000175000017500000000620510726351032023160 0ustar jhellstenjhellsten// ** I18N // Calendar SV language (Swedish, svenska) // Author: Mihai Bazon, // Translation team: // Translator: Leonard Norrgård // Last translator: Leonard Norrgård // Encoding: iso-latin-1 // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("söndag", "måndag", "tisdag", "onsdag", "torsdag", "fredag", "lördag", "söndag"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. Calendar._SDN_len = 2; Calendar._SMN_len = 3; // full month names Calendar._MN = new Array ("januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Om kalendern"; Calendar._TT["ABOUT"] = "DHTML Datum/tid-väljare\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "För senaste version gå till: http://www.dynarch.com/projects/calendar/\n" + "Distribueras under GNU LGPL. Se http://gnu.org/licenses/lgpl.html för detaljer." + "\n\n" + "Val av datum:\n" + "- Använd knapparna \xab, \xbb för att välja år\n" + "- Använd knapparna " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " för att välja månad\n" + "- Håll musknappen nedtryckt på någon av ovanstående knappar för snabbare val."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Val av tid:\n" + "- Klicka på en del av tiden för att öka den delen\n" + "- eller skift-klicka för att minska den\n" + "- eller klicka och drag för snabbare val."; Calendar._TT["PREV_YEAR"] = "Föregående år (håll för menu)"; Calendar._TT["PREV_MONTH"] = "Föregående månad (håll för menu)"; Calendar._TT["GO_TODAY"] = "Gå till dagens datum"; Calendar._TT["NEXT_MONTH"] = "Följande månad (håll för menu)"; Calendar._TT["NEXT_YEAR"] = "Följande år (håll för menu)"; Calendar._TT["SEL_DATE"] = "Välj datum"; Calendar._TT["DRAG_TO_MOVE"] = "Drag för att flytta"; Calendar._TT["PART_TODAY"] = " (idag)"; Calendar._TT["MON_FIRST"] = "Visa måndag först"; Calendar._TT["SUN_FIRST"] = "Visa söndag först"; Calendar._TT["CLOSE"] = "Stäng"; Calendar._TT["TODAY"] = "Idag"; Calendar._TT["TIME_PART"] = "(Skift-)klicka eller drag för att ändra tid"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%A %d %b %Y"; Calendar._TT["WK"] = "vecka"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-du.js0000644000175000017500000000216710726351032023143 0ustar jhellstenjhellsten// ** I18N Calendar._DN = new Array ("Zondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag", "Zondag"); Calendar._MN = new Array ("Januari", "Februari", "Maart", "April", "Mei", "Juni", "Juli", "Augustus", "September", "Oktober", "November", "December"); // tooltips Calendar._TT = {}; Calendar._TT["TOGGLE"] = "Toggle startdag van de week"; Calendar._TT["PREV_YEAR"] = "Vorig jaar (indrukken voor menu)"; Calendar._TT["PREV_MONTH"] = "Vorige month (indrukken voor menu)"; Calendar._TT["GO_TODAY"] = "Naar Vandaag"; Calendar._TT["NEXT_MONTH"] = "Volgende Maand (indrukken voor menu)"; Calendar._TT["NEXT_YEAR"] = "Volgend jaar (indrukken voor menu)"; Calendar._TT["SEL_DATE"] = "Selecteer datum"; Calendar._TT["DRAG_TO_MOVE"] = "Sleep om te verplaatsen"; Calendar._TT["PART_TODAY"] = " (vandaag)"; Calendar._TT["MON_FIRST"] = "Toon Maandag eerst"; Calendar._TT["SUN_FIRST"] = "Toon Zondag eerst"; Calendar._TT["CLOSE"] = "Sluiten"; Calendar._TT["TODAY"] = "Vandaag"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "y-mm-dd"; Calendar._TT["TT_DATE_FORMAT"] = "D, M d"; Calendar._TT["WK"] = "wk"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-no.js0000644000175000017500000000615210726351032023145 0ustar jhellstenjhellsten// ** I18N // Calendar NO language // Author: Daniel Holmen, // Encoding: UTF-8 // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag", "Søndag"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør", "Søn"); // full month names Calendar._MN = new Array ("Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"); // short month names Calendar._SMN = new Array ("Jan", "Feb", "Mar", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Des"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Om kalenderen"; Calendar._TT["ABOUT"] = "DHTML Dato-/Tidsvelger\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For nyeste versjon, gÃ¥ til: http://www.dynarch.com/projects/calendar/\n" + "Distribuert under GNU LGPL. Se http://gnu.org/licenses/lgpl.html for detaljer." + "\n\n" + "Datovalg:\n" + "- Bruk knappene \xab og \xbb for Ã¥ velge Ã¥r\n" + "- Bruk knappene " + String.fromCharCode(0x2039) + " og " + String.fromCharCode(0x203a) + " for Ã¥ velge mÃ¥ned\n" + "- Hold inne musknappen eller knappene over for raskere valg."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Tidsvalg:\n" + "- Klikk pÃ¥ en av tidsdelene for Ã¥ øke den\n" + "- eller Shift-klikk for Ã¥ senke verdien\n" + "- eller klikk-og-dra for raskere valg.."; Calendar._TT["PREV_YEAR"] = "Forrige. Ã¥r (hold for meny)"; Calendar._TT["PREV_MONTH"] = "Forrige. mÃ¥ned (hold for meny)"; Calendar._TT["GO_TODAY"] = "GÃ¥ til idag"; Calendar._TT["NEXT_MONTH"] = "Neste mÃ¥ned (hold for meny)"; Calendar._TT["NEXT_YEAR"] = "Neste Ã¥r (hold for meny)"; Calendar._TT["SEL_DATE"] = "Velg dato"; Calendar._TT["DRAG_TO_MOVE"] = "Dra for Ã¥ flytte"; Calendar._TT["PART_TODAY"] = " (idag)"; Calendar._TT["MON_FIRST"] = "Vis mandag først"; Calendar._TT["SUN_FIRST"] = "Vis søndag først"; Calendar._TT["CLOSE"] = "Lukk"; Calendar._TT["TODAY"] = "Idag"; Calendar._TT["TIME_PART"] = "(Shift-)Klikk eller dra for Ã¥ endre verdi"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["WK"] = "uke";nurpawiki-1.2.3/files/jscalendar/lang/calendar-zh.js0000644000175000017500000000601210726351032023145 0ustar jhellstenjhellsten// ** I18N // Calendar ZH language // Author: muziq, // Encoding: GB2312 or GBK // Distributed under the same terms as the calendar itself. // full day names Calendar._DN = new Array ("ÐÇÆÚÈÕ", "ÐÇÆÚÒ»", "ÐÇÆÚ¶þ", "ÐÇÆÚÈý", "ÐÇÆÚËÄ", "ÐÇÆÚÎå", "ÐÇÆÚÁù", "ÐÇÆÚÈÕ"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("ÈÕ", "Ò»", "¶þ", "Èý", "ËÄ", "Îå", "Áù", "ÈÕ"); // full month names Calendar._MN = new Array ("Ò»ÔÂ", "¶þÔÂ", "ÈýÔÂ", "ËÄÔÂ", "ÎåÔÂ", "ÁùÔÂ", "ÆßÔÂ", "°ËÔÂ", "¾ÅÔÂ", "Ê®ÔÂ", "ʮһÔÂ", "Ê®¶þÔÂ"); // short month names Calendar._SMN = new Array ("Ò»ÔÂ", "¶þÔÂ", "ÈýÔÂ", "ËÄÔÂ", "ÎåÔÂ", "ÁùÔÂ", "ÆßÔÂ", "°ËÔÂ", "¾ÅÔÂ", "Ê®ÔÂ", "ʮһÔÂ", "Ê®¶þÔÂ"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "°ïÖú"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "Ñ¡ÔñÈÕÆÚ:\n" + "- µã»÷ \xab, \xbb °´Å¥Ñ¡ÔñÄê·Ý\n" + "- µã»÷ " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " °´Å¥Ñ¡ÔñÔ·Ý\n" + "- ³¤°´ÒÔÉϰ´Å¥¿É´Ó²Ëµ¥ÖпìËÙÑ¡ÔñÄê·Ý»òÔ·Ý"; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Ñ¡Ôñʱ¼ä:\n" + "- µã»÷Сʱ»ò·ÖÖÓ¿Éʹ¸ÄÊýÖµ¼ÓÒ»\n" + "- °´×¡Shift¼üµã»÷Сʱ»ò·ÖÖÓ¿Éʹ¸ÄÊýÖµ¼õÒ»\n" + "- µã»÷Í϶¯Êó±ê¿É½øÐпìËÙÑ¡Ôñ"; Calendar._TT["PREV_YEAR"] = "ÉÏÒ»Äê (°´×¡³ö²Ëµ¥)"; Calendar._TT["PREV_MONTH"] = "ÉÏÒ»Ô (°´×¡³ö²Ëµ¥)"; Calendar._TT["GO_TODAY"] = "תµ½½ñÈÕ"; Calendar._TT["NEXT_MONTH"] = "ÏÂÒ»Ô (°´×¡³ö²Ëµ¥)"; Calendar._TT["NEXT_YEAR"] = "ÏÂÒ»Äê (°´×¡³ö²Ëµ¥)"; Calendar._TT["SEL_DATE"] = "Ñ¡ÔñÈÕÆÚ"; Calendar._TT["DRAG_TO_MOVE"] = "Í϶¯"; Calendar._TT["PART_TODAY"] = " (½ñÈÕ)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "×î×ó±ßÏÔʾ%s"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "¹Ø±Õ"; Calendar._TT["TODAY"] = "½ñÈÕ"; Calendar._TT["TIME_PART"] = "(Shift-)µã»÷Êó±ê»òÍ϶¯¸Ä±äÖµ"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%A, %b %eÈÕ"; Calendar._TT["WK"] = "ÖÜ"; Calendar._TT["TIME"] = "ʱ¼ä:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-tr.js0000644000175000017500000000331010726351032023147 0ustar jhellstenjhellsten////////////////////////////////////////////////////////////////////////////////////////////// // Turkish Translation by Nuri AKMAN // Location: Ankara/TURKEY // e-mail : nuriakman@hotmail.com // Date : April, 9 2003 // // Note: if Turkish Characters does not shown on you screen // please include falowing line your html code: // // // ////////////////////////////////////////////////////////////////////////////////////////////// // ** I18N Calendar._DN = new Array ("Pazar", "Pazartesi", "Salý", "Çarþamba", "Perþembe", "Cuma", "Cumartesi", "Pazar"); Calendar._MN = new Array ("Ocak", "Þubat", "Mart", "Nisan", "Mayýs", "Haziran", "Temmuz", "Aðustos", "Eylül", "Ekim", "Kasým", "Aralýk"); // tooltips Calendar._TT = {}; Calendar._TT["TOGGLE"] = "Haftanýn ilk gününü kaydýr"; Calendar._TT["PREV_YEAR"] = "Önceki Yýl (Menü için basýlý tutunuz)"; Calendar._TT["PREV_MONTH"] = "Önceki Ay (Menü için basýlý tutunuz)"; Calendar._TT["GO_TODAY"] = "Bugün'e git"; Calendar._TT["NEXT_MONTH"] = "Sonraki Ay (Menü için basýlý tutunuz)"; Calendar._TT["NEXT_YEAR"] = "Sonraki Yýl (Menü için basýlý tutunuz)"; Calendar._TT["SEL_DATE"] = "Tarih seçiniz"; Calendar._TT["DRAG_TO_MOVE"] = "Taþýmak için sürükleyiniz"; Calendar._TT["PART_TODAY"] = " (bugün)"; Calendar._TT["MON_FIRST"] = "Takvim Pazartesi gününden baþlasýn"; Calendar._TT["SUN_FIRST"] = "Takvim Pazar gününden baþlasýn"; Calendar._TT["CLOSE"] = "Kapat"; Calendar._TT["TODAY"] = "Bugün"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "dd-mm-y"; Calendar._TT["TT_DATE_FORMAT"] = "d MM y, DD"; Calendar._TT["WK"] = "Hafta"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-hr-utf8.js0000644000175000017500000000302110726351032024016 0ustar jhellstenjhellsten/* Croatian language file for the DHTML Calendar version 0.9.2 * Author Krunoslav Zubrinic , June 2003. * Feel free to use this script under the terms of the GNU Lesser General * Public License, as long as you do not remove or alter this notice. */ Calendar._DN = new Array ("Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "ÄŒetvrtak", "Petak", "Subota", "Nedjelja"); Calendar._MN = new Array ("SijeÄanj", "VeljaÄa", "Ožujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"); // tooltips Calendar._TT = {}; Calendar._TT["TOGGLE"] = "Promjeni dan s kojim poÄinje tjedan"; Calendar._TT["PREV_YEAR"] = "Prethodna godina (dugi pritisak za meni)"; Calendar._TT["PREV_MONTH"] = "Prethodni mjesec (dugi pritisak za meni)"; Calendar._TT["GO_TODAY"] = "Idi na tekući dan"; Calendar._TT["NEXT_MONTH"] = "Slijedeći mjesec (dugi pritisak za meni)"; Calendar._TT["NEXT_YEAR"] = "Slijedeća godina (dugi pritisak za meni)"; Calendar._TT["SEL_DATE"] = "Izaberite datum"; Calendar._TT["DRAG_TO_MOVE"] = "Pritisni i povuci za promjenu pozicije"; Calendar._TT["PART_TODAY"] = " (today)"; Calendar._TT["MON_FIRST"] = "Prikaži ponedjeljak kao prvi dan"; Calendar._TT["SUN_FIRST"] = "Prikaži nedjelju kao prvi dan"; Calendar._TT["CLOSE"] = "Zatvori"; Calendar._TT["TODAY"] = "Danas"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "dd-mm-y"; Calendar._TT["TT_DATE_FORMAT"] = "DD, dd.mm.y"; Calendar._TT["WK"] = "Tje";nurpawiki-1.2.3/files/jscalendar/lang/calendar-si.js0000644000175000017500000000517410726351032023147 0ustar jhellstenjhellsten/* Slovenian language file for the DHTML Calendar version 0.9.2 * Author David Milost , January 2004. * Feel free to use this script under the terms of the GNU Lesser General * Public License, as long as you do not remove or alter this notice. */ // full day names Calendar._DN = new Array ("Nedelja", "Ponedeljek", "Torek", "Sreda", "ÄŒetrtek", "Petek", "Sobota", "Nedelja"); // short day names Calendar._SDN = new Array ("Ned", "Pon", "Tor", "Sre", "ÄŒet", "Pet", "Sob", "Ned"); // short month names Calendar._SMN = new Array ("Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Avg", "Sep", "Okt", "Nov", "Dec"); // full month names Calendar._MN = new Array ("Januar", "Februar", "Marec", "April", "Maj", "Junij", "Julij", "Avgust", "September", "Oktober", "November", "December"); // tooltips // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "O koledarju"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "Za zadnjo verzijo pojdine na naslov: http://www.dynarch.com/projects/calendar/\n" + "Distribuirano pod GNU LGPL. Poglejte http://gnu.org/licenses/lgpl.html za podrobnosti." + "\n\n" + "Izbor datuma:\n" + "- Uporabite \xab, \xbb gumbe za izbor leta\n" + "- Uporabite " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " gumbe za izbor meseca\n" + "- Zadržite klik na kateremkoli od zgornjih gumbov za hiter izbor."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Izbor ćasa:\n" + "- Kliknite na katerikoli del ćasa za poveć. le-tega\n" + "- ali Shift-click za zmanj. le-tega\n" + "- ali kliknite in povlecite za hiter izbor."; Calendar._TT["TOGGLE"] = "Spremeni dan s katerim se prićne teden"; Calendar._TT["PREV_YEAR"] = "Predhodnje leto (dolg klik za meni)"; Calendar._TT["PREV_MONTH"] = "Predhodnji mesec (dolg klik za meni)"; Calendar._TT["GO_TODAY"] = "Pojdi na tekoći dan"; Calendar._TT["NEXT_MONTH"] = "Naslednji mesec (dolg klik za meni)"; Calendar._TT["NEXT_YEAR"] = "Naslednje leto (dolg klik za meni)"; Calendar._TT["SEL_DATE"] = "Izberite datum"; Calendar._TT["DRAG_TO_MOVE"] = "Pritisni in povleci za spremembo pozicije"; Calendar._TT["PART_TODAY"] = " (danes)"; Calendar._TT["MON_FIRST"] = "Prikaži ponedeljek kot prvi dan"; Calendar._TT["SUN_FIRST"] = "Prikaži nedeljo kot prvi dan"; Calendar._TT["CLOSE"] = "Zapri"; Calendar._TT["TODAY"] = "Danes"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["WK"] = "Ted";nurpawiki-1.2.3/files/jscalendar/lang/calendar-de.js0000644000175000017500000000742710726351032023127 0ustar jhellstenjhellsten// ** I18N // Calendar DE language // Author: Jack (tR), // Encoding: any // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"); // full month names Calendar._MN = new Array ("Januar", "Februar", "M\u00e4rz", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"); // short month names Calendar._SMN = new Array ("Jan", "Feb", "M\u00e4r", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "\u00DCber dieses Kalendarmodul"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this ;-) "For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "Datum ausw\u00e4hlen:\n" + "- Benutzen Sie die \xab, \xbb Buttons um das Jahr zu w\u00e4hlen\n" + "- Benutzen Sie die " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " Buttons um den Monat zu w\u00e4hlen\n" + "- F\u00fcr eine Schnellauswahl halten Sie die Maustaste \u00fcber diesen Buttons fest."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Zeit ausw\u00e4hlen:\n" + "- Klicken Sie auf die Teile der Uhrzeit, um diese zu erh\u00F6hen\n" + "- oder klicken Sie mit festgehaltener Shift-Taste um diese zu verringern\n" + "- oder klicken und festhalten f\u00fcr Schnellauswahl."; Calendar._TT["TOGGLE"] = "Ersten Tag der Woche w\u00e4hlen"; Calendar._TT["PREV_YEAR"] = "Voriges Jahr (Festhalten f\u00fcr Schnellauswahl)"; Calendar._TT["PREV_MONTH"] = "Voriger Monat (Festhalten f\u00fcr Schnellauswahl)"; Calendar._TT["GO_TODAY"] = "Heute ausw\u00e4hlen"; Calendar._TT["NEXT_MONTH"] = "N\u00e4chst. Monat (Festhalten f\u00fcr Schnellauswahl)"; Calendar._TT["NEXT_YEAR"] = "N\u00e4chst. Jahr (Festhalten f\u00fcr Schnellauswahl)"; Calendar._TT["SEL_DATE"] = "Datum ausw\u00e4hlen"; Calendar._TT["DRAG_TO_MOVE"] = "Zum Bewegen festhalten"; Calendar._TT["PART_TODAY"] = " (Heute)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Woche beginnt mit %s "; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Schlie\u00dfen"; Calendar._TT["TODAY"] = "Heute"; Calendar._TT["TIME_PART"] = "(Shift-)Klick oder Festhalten und Ziehen um den Wert zu \u00e4ndern"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["WK"] = "wk"; Calendar._TT["TIME"] = "Zeit:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-hu.js0000644000175000017500000000702310726351032023143 0ustar jhellstenjhellsten// ** I18N // Calendar HU language // Author: ??? // Modifier: KARASZI Istvan, // Encoding: any // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Vasárnap", "Hétfõ", "Kedd", "Szerda", "Csütörtök", "Péntek", "Szombat", "Vasárnap"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("v", "h", "k", "sze", "cs", "p", "szo", "v"); // full month names Calendar._MN = new Array ("január", "február", "március", "április", "május", "június", "július", "augusztus", "szeptember", "október", "november", "december"); // short month names Calendar._SMN = new Array ("jan", "feb", "már", "ápr", "máj", "jún", "júl", "aug", "sze", "okt", "nov", "dec"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "A kalendáriumról"; Calendar._TT["ABOUT"] = "DHTML dátum/idõ kiválasztó\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "a legfrissebb verzió megtalálható: http://www.dynarch.com/projects/calendar/\n" + "GNU LGPL alatt terjesztve. Lásd a http://gnu.org/licenses/lgpl.html oldalt a részletekhez." + "\n\n" + "Dátum választás:\n" + "- használja a \xab, \xbb gombokat az év kiválasztásához\n" + "- használja a " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " gombokat a hónap kiválasztásához\n" + "- tartsa lenyomva az egérgombot a gyors választáshoz."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Idõ választás:\n" + "- kattintva növelheti az idõt\n" + "- shift-tel kattintva csökkentheti\n" + "- lenyomva tartva és húzva gyorsabban kiválaszthatja."; Calendar._TT["PREV_YEAR"] = "Elõzõ év (tartsa nyomva a menühöz)"; Calendar._TT["PREV_MONTH"] = "Elõzõ hónap (tartsa nyomva a menühöz)"; Calendar._TT["GO_TODAY"] = "Mai napra ugrás"; Calendar._TT["NEXT_MONTH"] = "Köv. hónap (tartsa nyomva a menühöz)"; Calendar._TT["NEXT_YEAR"] = "Köv. év (tartsa nyomva a menühöz)"; Calendar._TT["SEL_DATE"] = "Válasszon dátumot"; Calendar._TT["DRAG_TO_MOVE"] = "Húzza a mozgatáshoz"; Calendar._TT["PART_TODAY"] = " (ma)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "%s legyen a hét elsõ napja"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Bezár"; Calendar._TT["TODAY"] = "Ma"; Calendar._TT["TIME_PART"] = "(Shift-)Klikk vagy húzás az érték változtatásához"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%b %e, %a"; Calendar._TT["WK"] = "hét"; Calendar._TT["TIME"] = "idõ:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-al.js0000644000175000017500000000412710726351032023125 0ustar jhellstenjhellsten// Calendar ALBANIAN language //author Rigels Gordani rige@hotmail.com // ditet Calendar._DN = new Array ("E Diele", "E Hene", "E Marte", "E Merkure", "E Enjte", "E Premte", "E Shtune", "E Diele"); //ditet shkurt Calendar._SDN = new Array ("Die", "Hen", "Mar", "Mer", "Enj", "Pre", "Sht", "Die"); // muajt Calendar._MN = new Array ("Janar", "Shkurt", "Mars", "Prill", "Maj", "Qeshor", "Korrik", "Gusht", "Shtator", "Tetor", "Nentor", "Dhjetor"); // muajte shkurt Calendar._SMN = new Array ("Jan", "Shk", "Mar", "Pri", "Maj", "Qes", "Kor", "Gus", "Sht", "Tet", "Nen", "Dhj"); // ndihmesa Calendar._TT = {}; Calendar._TT["INFO"] = "Per kalendarin"; Calendar._TT["ABOUT"] = "Zgjedhes i ores/dates ne DHTML \n" + "\n\n" +"Zgjedhja e Dates:\n" + "- Perdor butonat \xab, \xbb per te zgjedhur vitin\n" + "- Perdor butonat" + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " per te zgjedhur muajin\n" + "- Mbani shtypur butonin e mousit per nje zgjedje me te shpejte."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Zgjedhja e kohes:\n" + "- Kliko tek ndonje nga pjeset e ores per ta rritur ate\n" + "- ose kliko me Shift per ta zvogeluar ate\n" + "- ose cliko dhe terhiq per zgjedhje me te shpejte."; Calendar._TT["PREV_YEAR"] = "Viti i shkuar (prit per menune)"; Calendar._TT["PREV_MONTH"] = "Muaji i shkuar (prit per menune)"; Calendar._TT["GO_TODAY"] = "Sot"; Calendar._TT["NEXT_MONTH"] = "Muaji i ardhshem (prit per menune)"; Calendar._TT["NEXT_YEAR"] = "Viti i ardhshem (prit per menune)"; Calendar._TT["SEL_DATE"] = "Zgjidh daten"; Calendar._TT["DRAG_TO_MOVE"] = "Terhiqe per te levizur"; Calendar._TT["PART_TODAY"] = " (sot)"; // "%s" eshte dita e pare e javes // %s do te zevendesohet me emrin e dite Calendar._TT["DAY_FIRST"] = "Trego te %s te paren"; Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Mbyll"; Calendar._TT["TODAY"] = "Sot"; Calendar._TT["TIME_PART"] = "Kliko me (Shift-)ose terhiqe per te ndryshuar vleren"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["WK"] = "Java"; Calendar._TT["TIME"] = "Koha:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-ru.js0000644000175000017500000001040510726351032023153 0ustar jhellstenjhellsten// ** I18N // Calendar RU language // Translation: Sly Golovanov, http://golovanov.net, // Encoding: any // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("воÑкреÑенье", "понедельник", "вторник", "Ñреда", "четверг", "пÑтница", "Ñуббота", "воÑкреÑенье"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("вÑк", "пон", "втр", "Ñрд", "чет", "пÑÑ‚", "Ñуб", "вÑк"); // full month names Calendar._MN = new Array ("Ñнварь", "февраль", "март", "апрель", "май", "июнь", "июль", "авгуÑÑ‚", "ÑентÑбрь", "октÑбрь", "ноÑбрь", "декабрь"); // short month names Calendar._SMN = new Array ("Ñнв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "Ñен", "окт", "ноÑ", "дек"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "О календаре..."; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "Как выбрать дату:\n" + "- При помощи кнопок \xab, \xbb можно выбрать год\n" + "- При помощи кнопок " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " можно выбрать меÑÑц\n" + "- Подержите Ñти кнопки нажатыми, чтобы поÑвилоÑÑŒ меню быÑтрого выбора."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Как выбрать времÑ:\n" + "- При клике на чаÑах или минутах они увеличиваютÑÑ\n" + "- при клике Ñ Ð½Ð°Ð¶Ð°Ñ‚Ð¾Ð¹ клавишей Shift они уменьшаютÑÑ\n" + "- еÑли нажать и двигать мышкой влево/вправо, они будут менÑтьÑÑ Ð±Ñ‹Ñтрее."; Calendar._TT["PREV_YEAR"] = "Ðа год назад (удерживать Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)"; Calendar._TT["PREV_MONTH"] = "Ðа меÑÑц назад (удерживать Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)"; Calendar._TT["GO_TODAY"] = "СегоднÑ"; Calendar._TT["NEXT_MONTH"] = "Ðа меÑÑц вперед (удерживать Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)"; Calendar._TT["NEXT_YEAR"] = "Ðа год вперед (удерживать Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)"; Calendar._TT["SEL_DATE"] = "Выберите дату"; Calendar._TT["DRAG_TO_MOVE"] = "ПеретаÑкивайте мышкой"; Calendar._TT["PART_TODAY"] = " (ÑегоднÑ)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Первый день недели будет %s"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Закрыть"; Calendar._TT["TODAY"] = "СегоднÑ"; Calendar._TT["TIME_PART"] = "(Shift-)клик или нажать и двигать"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%e %b, %a"; Calendar._TT["WK"] = "нед"; Calendar._TT["TIME"] = "ВремÑ:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-fi.js0000644000175000017500000000533610726351032023132 0ustar jhellstenjhellsten// ** I18N // Calendar FI language (Finnish, Suomi) // Author: Jarno Käyhkö, // Encoding: UTF-8 // Distributed under the same terms as the calendar itself. // full day names Calendar._DN = new Array ("Sunnuntai", "Maanantai", "Tiistai", "Keskiviikko", "Torstai", "Perjantai", "Lauantai", "Sunnuntai"); // short day names Calendar._SDN = new Array ("Su", "Ma", "Ti", "Ke", "To", "Pe", "La", "Su"); // full month names Calendar._MN = new Array ("Tammikuu", "Helmikuu", "Maaliskuu", "Huhtikuu", "Toukokuu", "Kesäkuu", "Heinäkuu", "Elokuu", "Syyskuu", "Lokakuu", "Marraskuu", "Joulukuu"); // short month names Calendar._SMN = new Array ("Tam", "Hel", "Maa", "Huh", "Tou", "Kes", "Hei", "Elo", "Syy", "Lok", "Mar", "Jou"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Tietoja kalenterista"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "Uusin versio osoitteessa: http://www.dynarch.com/projects/calendar/\n" + "Julkaistu GNU LGPL lisenssin alaisuudessa. Lisätietoja osoitteessa http://gnu.org/licenses/lgpl.html" + "\n\n" + "Päivämäärä valinta:\n" + "- Käytä \xab, \xbb painikkeita valitaksesi vuosi\n" + "- Käytä " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " painikkeita valitaksesi kuukausi\n" + "- Pitämällä hiiren painiketta minkä tahansa yllä olevan painikkeen kohdalla, saat näkyviin valikon nopeampaan siirtymiseen."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Ajan valinta:\n" + "- Klikkaa kellonajan numeroita lisätäksesi aikaa\n" + "- tai pitämällä Shift-näppäintä pohjassa saat aikaa taaksepäin\n" + "- tai klikkaa ja pidä hiiren painike pohjassa sekä liikuta hiirtä muuttaaksesi aikaa nopeasti eteen- ja taaksepäin."; Calendar._TT["PREV_YEAR"] = "Edell. vuosi (paina hetki, näet valikon)"; Calendar._TT["PREV_MONTH"] = "Edell. kuukausi (paina hetki, näet valikon)"; Calendar._TT["GO_TODAY"] = "Siirry tähän päivään"; Calendar._TT["NEXT_MONTH"] = "Seur. kuukausi (paina hetki, näet valikon)"; Calendar._TT["NEXT_YEAR"] = "Seur. vuosi (paina hetki, näet valikon)"; Calendar._TT["SEL_DATE"] = "Valitse päivämäärä"; Calendar._TT["DRAG_TO_MOVE"] = "Siirrä kalenterin paikkaa"; Calendar._TT["PART_TODAY"] = " (tänään)"; Calendar._TT["MON_FIRST"] = "Näytä maanantai ensimmäisenä"; Calendar._TT["SUN_FIRST"] = "Näytä sunnuntai ensimmäisenä"; Calendar._TT["CLOSE"] = "Sulje"; Calendar._TT["TODAY"] = "Tänään"; Calendar._TT["TIME_PART"] = "(Shift-) Klikkaa tai liikuta muuttaaksesi aikaa"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y"; Calendar._TT["TT_DATE_FORMAT"] = "%d.%m.%Y"; Calendar._TT["WK"] = "Vko"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-fr.js0000644000175000017500000000723710726351032023145 0ustar jhellstenjhellsten// ** I18N // Calendar EN language // Author: Mihai Bazon, // Encoding: any // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // Translator: David Duret, from previous french version // full day names Calendar._DN = new Array ("Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("Dim", "Lun", "Mar", "Mar", "Jeu", "Ven", "Sam", "Dim"); // full month names Calendar._MN = new Array ("Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"); // short month names Calendar._SMN = new Array ("Jan", "Fev", "Mar", "Avr", "Mai", "Juin", "Juil", "Aout", "Sep", "Oct", "Nov", "Dec"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "A propos du calendrier"; Calendar._TT["ABOUT"] = "DHTML Date/Heure Selecteur\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "Pour la derniere version visitez : http://www.dynarch.com/projects/calendar/\n" + "Distribué par GNU LGPL. Voir http://gnu.org/licenses/lgpl.html pour les details." + "\n\n" + "Selection de la date :\n" + "- Utiliser les bouttons \xab, \xbb pour selectionner l\'annee\n" + "- Utiliser les bouttons " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " pour selectionner les mois\n" + "- Garder la souris sur n'importe quels boutons pour une selection plus rapide"; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Selection de l\'heure :\n" + "- Cliquer sur heures ou minutes pour incrementer\n" + "- ou Maj-clic pour decrementer\n" + "- ou clic et glisser-deplacer pour une selection plus rapide"; Calendar._TT["PREV_YEAR"] = "Année préc. (maintenir pour menu)"; Calendar._TT["PREV_MONTH"] = "Mois préc. (maintenir pour menu)"; Calendar._TT["GO_TODAY"] = "Atteindre la date du jour"; Calendar._TT["NEXT_MONTH"] = "Mois suiv. (maintenir pour menu)"; Calendar._TT["NEXT_YEAR"] = "Année suiv. (maintenir pour menu)"; Calendar._TT["SEL_DATE"] = "Sélectionner une date"; Calendar._TT["DRAG_TO_MOVE"] = "Déplacer"; Calendar._TT["PART_TODAY"] = " (Aujourd'hui)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Afficher %s en premier"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Fermer"; Calendar._TT["TODAY"] = "Aujourd'hui"; Calendar._TT["TIME_PART"] = "(Maj-)Clic ou glisser pour modifier la valeur"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["WK"] = "Sem."; Calendar._TT["TIME"] = "Heure :"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-pl.js0000644000175000017500000000455610726351032023152 0ustar jhellstenjhellsten// ** I18N // Calendar PL language // Author: Artur Filipiak, // January, 2004 // Encoding: UTF-8 Calendar._DN = new Array ("Niedziela", "PoniedziaÅ‚ek", "Wtorek", "Åšroda", "Czwartek", "PiÄ…tek", "Sobota", "Niedziela"); Calendar._SDN = new Array ("N", "Pn", "Wt", "Åšr", "Cz", "Pt", "So", "N"); Calendar._MN = new Array ("StyczeÅ„", "Luty", "Marzec", "KwiecieÅ„", "Maj", "Czerwiec", "Lipiec", "SierpieÅ„", "WrzesieÅ„", "Październik", "Listopad", "GrudzieÅ„"); Calendar._SMN = new Array ("Sty", "Lut", "Mar", "Kwi", "Maj", "Cze", "Lip", "Sie", "Wrz", "Paź", "Lis", "Gru"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "O kalendarzu"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "Wybór daty:\n" + "- aby wybrać rok użyj przycisków \xab, \xbb\n" + "- aby wybrać miesiÄ…c użyj przycisków " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "\n" + "- aby przyspieszyć wybór przytrzymaj wciÅ›niÄ™ty przycisk myszy nad ww. przyciskami."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Wybór czasu:\n" + "- aby zwiÄ™kszyć wartość kliknij na dowolnym elemencie selekcji czasu\n" + "- aby zmniejszyć wartość użyj dodatkowo klawisza Shift\n" + "- możesz również poruszać myszkÄ™ w lewo i prawo wraz z wciÅ›niÄ™tym lewym klawiszem."; Calendar._TT["PREV_YEAR"] = "Poprz. rok (przytrzymaj dla menu)"; Calendar._TT["PREV_MONTH"] = "Poprz. miesiÄ…c (przytrzymaj dla menu)"; Calendar._TT["GO_TODAY"] = "Pokaż dziÅ›"; Calendar._TT["NEXT_MONTH"] = "Nast. miesiÄ…c (przytrzymaj dla menu)"; Calendar._TT["NEXT_YEAR"] = "Nast. rok (przytrzymaj dla menu)"; Calendar._TT["SEL_DATE"] = "Wybierz datÄ™"; Calendar._TT["DRAG_TO_MOVE"] = "PrzesuÅ„ okienko"; Calendar._TT["PART_TODAY"] = " (dziÅ›)"; Calendar._TT["MON_FIRST"] = "Pokaż PoniedziaÅ‚ek jako pierwszy"; Calendar._TT["SUN_FIRST"] = "Pokaż NiedzielÄ™ jako pierwszÄ…"; Calendar._TT["CLOSE"] = "Zamknij"; Calendar._TT["TODAY"] = "DziÅ›"; Calendar._TT["TIME_PART"] = "(Shift-)klik | drag, aby zmienić wartość"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y.%m.%d"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["WK"] = "wk";nurpawiki-1.2.3/files/jscalendar/lang/calendar-sk.js0000644000175000017500000000514510726351032023147 0ustar jhellstenjhellsten// ** I18N // Calendar SK language // Author: Peter Valach (pvalach@gmx.net) // Encoding: utf-8 // Last update: 2003/10/29 // Distributed under the same terms as the calendar itself. // full day names Calendar._DN = new Array ("NedeÄľa", "Pondelok", "Utorok", "Streda", "Ĺ tvrtok", "Piatok", "Sobota", "NedeÄľa"); // short day names Calendar._SDN = new Array ("Ned", "Pon", "Uto", "Str", "Ĺ tv", "Pia", "Sob", "Ned"); // full month names Calendar._MN = new Array ("Január", "Február", "Marec", "AprĂ­l", "Máj", "JĂşn", "JĂşl", "August", "September", "OktĂłber", "November", "December"); // short month names Calendar._SMN = new Array ("Jan", "Feb", "Mar", "Apr", "Máj", "JĂşn", "JĂşl", "Aug", "Sep", "Okt", "Nov", "Dec"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "O kalendári"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + "PoslednĂş verziu nájdete na: http://www.dynarch.com/projects/calendar/\n" + "DistribuovanĂ© pod GNU LGPL. ViÄŹ http://gnu.org/licenses/lgpl.html pre detaily." + "\n\n" + "VÄ‚Ëber dátumu:\n" + "- PouĹľite tlaÄŤidlá \xab, \xbb pre vÄ‚Ëber roku\n" + "- PouĹľite tlaÄŤidlá " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " pre vÄ‚Ëber mesiaca\n" + "- Ak ktorĂ©koÄľvek z tÄ‚Ëchto tlaÄŤidiel podržíte dlhšie, zobrazĂ­ sa rÄ‚Ëchly vÄ‚Ëber."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "VÄ‚Ëber ÄŤasu:\n" + "- Kliknutie na niektorĂş poloĹľku ÄŤasu ju zvĂ˚i\n" + "- Shift-klik ju znĂ­Ĺľi\n" + "- Ak podržíte tlaÄŤĂ­tko stlaÄŤenĂ©, posĂşvanĂ­m menĂ­te hodnotu."; Calendar._TT["PREV_YEAR"] = "PredošlÄ‚Ë rok (podrĹľte pre menu)"; Calendar._TT["PREV_MONTH"] = "PredošlÄ‚Ë mesiac (podrĹľte pre menu)"; Calendar._TT["GO_TODAY"] = "PrejsĹĄ na dnešok"; Calendar._TT["NEXT_MONTH"] = "Nasl. mesiac (podrĹľte pre menu)"; Calendar._TT["NEXT_YEAR"] = "Nasl. rok (podrĹľte pre menu)"; Calendar._TT["SEL_DATE"] = "ZvoÄľte dátum"; Calendar._TT["DRAG_TO_MOVE"] = "PodrĹľanĂ­m tlaÄŤĂ­tka zmenĂ­te polohu"; Calendar._TT["PART_TODAY"] = " (dnes)"; Calendar._TT["MON_FIRST"] = "ZobraziĹĄ pondelok ako prvÄ‚Ë"; Calendar._TT["SUN_FIRST"] = "ZobraziĹĄ nedeÄľu ako prvĂş"; Calendar._TT["CLOSE"] = "ZavrieĹĄ"; Calendar._TT["TODAY"] = "Dnes"; Calendar._TT["TIME_PART"] = "(Shift-)klik/ĹĄahanie zmenĂ­ hodnotu"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "$d. %m. %Y"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %e. %b"; Calendar._TT["WK"] = "tÄ‚ËĹľ"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-bg.js0000644000175000017500000000721310726351032023120 0ustar jhellstenjhellsten// ** I18N // Calendar BG language // Author: Mihai Bazon, // Translator: Valentin Sheiretsky, // Encoding: Windows-1251 // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Íåäåëÿ", "Ïîíåäåëíèê", "Âòîðíèê", "Ñðÿäà", "×åòâúðòúê", "Ïåòúê", "Ñúáîòà", "Íåäåëÿ"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("Íåä", "Ïîí", "Âòî", "Ñðÿ", "×åò", "Ïåò", "Ñúá", "Íåä"); // full month names Calendar._MN = new Array ("ßíóàðè", "Ôåâðóàðè", "Ìàðò", "Àïðèë", "Ìàé", "Þíè", "Þëè", "Àâãóñò", "Ñåïòåìâðè", "Îêòîìâðè", "Íîåìâðè", "Äåêåìâðè"); // short month names Calendar._SMN = new Array ("ßíó", "Ôåâ", "Ìàð", "Àïð", "Ìàé", "Þíè", "Þëè", "Àâã", "Ñåï", "Îêò", "Íîå", "Äåê"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Èíôîðìàöèÿ çà êàëåíäàðà"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "Date selection:\n" + "- Use the \xab, \xbb buttons to select year\n" + "- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" + "- Hold mouse button on any of the above buttons for faster selection."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Time selection:\n" + "- Click on any of the time parts to increase it\n" + "- or Shift-click to decrease it\n" + "- or click and drag for faster selection."; Calendar._TT["PREV_YEAR"] = "Ïðåäíà ãîäèíà (çàäðúæòå çà ìåíþ)"; Calendar._TT["PREV_MONTH"] = "Ïðåäåí ìåñåö (çàäðúæòå çà ìåíþ)"; Calendar._TT["GO_TODAY"] = "Èçáåðåòå äíåñ"; Calendar._TT["NEXT_MONTH"] = "Ñëåäâàù ìåñåö (çàäðúæòå çà ìåíþ)"; Calendar._TT["NEXT_YEAR"] = "Ñëåäâàùà ãîäèíà (çàäðúæòå çà ìåíþ)"; Calendar._TT["SEL_DATE"] = "Èçáåðåòå äàòà"; Calendar._TT["DRAG_TO_MOVE"] = "Ïðåìåñòâàíå"; Calendar._TT["PART_TODAY"] = " (äíåñ)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "%s êàòî ïúðâè äåí"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Çàòâîðåòå"; Calendar._TT["TODAY"] = "Äíåñ"; Calendar._TT["TIME_PART"] = "(Shift-)Click èëè drag çà äà ïðîìåíèòå ñòîéíîñòòà"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%A - %e %B %Y"; Calendar._TT["WK"] = "Ñåäì"; Calendar._TT["TIME"] = "×àñ:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-af.js0000644000175000017500000000176310726351032023122 0ustar jhellstenjhellsten// ** I18N Afrikaans Calendar._DN = new Array ("Sondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrydag", "Saterdag", "Sondag"); Calendar._MN = new Array ("Januarie", "Februarie", "Maart", "April", "Mei", "Junie", "Julie", "Augustus", "September", "Oktober", "November", "Desember"); // tooltips Calendar._TT = {}; Calendar._TT["TOGGLE"] = "Verander eerste dag van die week"; Calendar._TT["PREV_YEAR"] = "Vorige jaar (hou vir keuselys)"; Calendar._TT["PREV_MONTH"] = "Vorige maand (hou vir keuselys)"; Calendar._TT["GO_TODAY"] = "Gaan na vandag"; Calendar._TT["NEXT_MONTH"] = "Volgende maand (hou vir keuselys)"; Calendar._TT["NEXT_YEAR"] = "Volgende jaar (hou vir keuselys)"; Calendar._TT["SEL_DATE"] = "Kies datum"; Calendar._TT["DRAG_TO_MOVE"] = "Sleep om te skuif"; Calendar._TT["PART_TODAY"] = " (vandag)"; Calendar._TT["MON_FIRST"] = "Vertoon Maandag eerste"; Calendar._TT["SUN_FIRST"] = "Display Sunday first"; Calendar._TT["CLOSE"] = "Close"; Calendar._TT["TODAY"] = "Today"; nurpawiki-1.2.3/files/jscalendar/lang/cn_utf8.js0000644000175000017500000001102610726351032022324 0ustar jhellstenjhellsten// ** I18N // Calendar EN language // Author: Mihai Bazon, // Encoding: any // Translator : Niko // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("\u5468\u65e5",//\u5468\u65e5 "\u5468\u4e00",//\u5468\u4e00 "\u5468\u4e8c",//\u5468\u4e8c "\u5468\u4e09",//\u5468\u4e09 "\u5468\u56db",//\u5468\u56db "\u5468\u4e94",//\u5468\u4e94 "\u5468\u516d",//\u5468\u516d "\u5468\u65e5");//\u5468\u65e5 // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("\u5468\u65e5", "\u5468\u4e00", "\u5468\u4e8c", "\u5468\u4e09", "\u5468\u56db", "\u5468\u4e94", "\u5468\u516d", "\u5468\u65e5"); // full month names Calendar._MN = new Array ("\u4e00\u6708", "\u4e8c\u6708", "\u4e09\u6708", "\u56db\u6708", "\u4e94\u6708", "\u516d\u6708", "\u4e03\u6708", "\u516b\u6708", "\u4e5d\u6708", "\u5341\u6708", "\u5341\u4e00\u6708", "\u5341\u4e8c\u6708"); // short month names Calendar._SMN = new Array ("\u4e00\u6708", "\u4e8c\u6708", "\u4e09\u6708", "\u56db\u6708", "\u4e94\u6708", "\u516d\u6708", "\u4e03\u6708", "\u516b\u6708", "\u4e5d\u6708", "\u5341\u6708", "\u5341\u4e00\u6708", "\u5341\u4e8c\u6708"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "\u5173\u4e8e"; Calendar._TT["ABOUT"] = " DHTML \u65e5\u8d77/\u65f6\u95f4\u9009\u62e9\u63a7\u4ef6\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For latest version visit: \u6700\u65b0\u7248\u672c\u8bf7\u767b\u9646http://www.dynarch.com/projects/calendar/\u5bdf\u770b\n" + "\u9075\u5faaGNU LGPL. \u7ec6\u8282\u53c2\u9605 http://gnu.org/licenses/lgpl.html" + "\n\n" + "\u65e5\u671f\u9009\u62e9:\n" + "- \u70b9\u51fb\xab(\xbb)\u6309\u94ae\u9009\u62e9\u4e0a(\u4e0b)\u4e00\u5e74\u5ea6.\n" + "- \u70b9\u51fb" + String.fromCharCode(0x2039) + "(" + String.fromCharCode(0x203a) + ")\u6309\u94ae\u9009\u62e9\u4e0a(\u4e0b)\u4e2a\u6708\u4efd.\n" + "- \u957f\u65f6\u95f4\u6309\u7740\u6309\u94ae\u5c06\u51fa\u73b0\u66f4\u591a\u9009\u62e9\u9879."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "\u65f6\u95f4\u9009\u62e9:\n" + "-\u5728\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)\u4e0a\u5355\u51fb\u9f20\u6807\u5de6\u952e\u6765\u589e\u52a0\u5f53\u524d\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)\n" + "-\u5728\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)\u4e0a\u6309\u4f4fShift\u952e\u540e\u5355\u51fb\u9f20\u6807\u5de6\u952e\u6765\u51cf\u5c11\u5f53\u524d\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)."; Calendar._TT["PREV_YEAR"] = "\u4e0a\u4e00\u5e74"; Calendar._TT["PREV_MONTH"] = "\u4e0a\u4e2a\u6708"; Calendar._TT["GO_TODAY"] = "\u5230\u4eca\u5929"; Calendar._TT["NEXT_MONTH"] = "\u4e0b\u4e2a\u6708"; Calendar._TT["NEXT_YEAR"] = "\u4e0b\u4e00\u5e74"; Calendar._TT["SEL_DATE"] = "\u9009\u62e9\u65e5\u671f"; Calendar._TT["DRAG_TO_MOVE"] = "\u62d6\u52a8"; Calendar._TT["PART_TODAY"] = " (\u4eca\u5929)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "%s\u4e3a\u8fd9\u5468\u7684\u7b2c\u4e00\u5929"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "\u5173\u95ed"; Calendar._TT["TODAY"] = "\u4eca\u5929"; Calendar._TT["TIME_PART"] = "(\u6309\u7740Shift\u952e)\u5355\u51fb\u6216\u62d6\u52a8\u6539\u53d8\u503c"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e\u65e5"; Calendar._TT["WK"] = "\u5468"; Calendar._TT["TIME"] = "\u65f6\u95f4:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-pt.js0000644000175000017500000000670610726351032023161 0ustar jhellstenjhellsten// ** I18N // Calendar pt_BR language // Author: Adalberto Machado, // Encoding: any // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Domingo", "Segunda", "Terca", "Quarta", "Quinta", "Sexta", "Sabado", "Domingo"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab", "Dom"); // full month names Calendar._MN = new Array ("Janeiro", "Fevereiro", "Marco", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"); // short month names Calendar._SMN = new Array ("Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Sobre o calendario"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "Ultima versao visite: http://www.dynarch.com/projects/calendar/\n" + "Distribuido sobre GNU LGPL. Veja http://gnu.org/licenses/lgpl.html para detalhes." + "\n\n" + "Selecao de data:\n" + "- Use os botoes \xab, \xbb para selecionar o ano\n" + "- Use os botoes " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para selecionar o mes\n" + "- Segure o botao do mouse em qualquer um desses botoes para selecao rapida."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Selecao de hora:\n" + "- Clique em qualquer parte da hora para incrementar\n" + "- ou Shift-click para decrementar\n" + "- ou clique e segure para selecao rapida."; Calendar._TT["PREV_YEAR"] = "Ant. ano (segure para menu)"; Calendar._TT["PREV_MONTH"] = "Ant. mes (segure para menu)"; Calendar._TT["GO_TODAY"] = "Hoje"; Calendar._TT["NEXT_MONTH"] = "Prox. mes (segure para menu)"; Calendar._TT["NEXT_YEAR"] = "Prox. ano (segure para menu)"; Calendar._TT["SEL_DATE"] = "Selecione a data"; Calendar._TT["DRAG_TO_MOVE"] = "Arraste para mover"; Calendar._TT["PART_TODAY"] = " (hoje)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Mostre %s primeiro"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Fechar"; Calendar._TT["TODAY"] = "Hoje"; Calendar._TT["TIME_PART"] = "(Shift-)Click ou arraste para mudar valor"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %e %b"; Calendar._TT["WK"] = "sm"; Calendar._TT["TIME"] = "Hora:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-pl-utf8.js0000644000175000017500000000511310726351032024024 0ustar jhellstenjhellsten// ** I18N // Calendar PL language // Author: Dariusz Pietrzak, // Author: Janusz Piwowarski, // Encoding: utf-8 // Distributed under the same terms as the calendar itself. Calendar._DN = new Array ("Niedziela", "PoniedziaÅ‚ek", "Wtorek", "Åšroda", "Czwartek", "PiÄ…tek", "Sobota", "Niedziela"); Calendar._SDN = new Array ("Nie", "Pn", "Wt", "Åšr", "Cz", "Pt", "So", "Nie"); Calendar._MN = new Array ("StyczeÅ„", "Luty", "Marzec", "KwiecieÅ„", "Maj", "Czerwiec", "Lipiec", "SierpieÅ„", "WrzesieÅ„", "Październik", "Listopad", "GrudzieÅ„"); Calendar._SMN = new Array ("Sty", "Lut", "Mar", "Kwi", "Maj", "Cze", "Lip", "Sie", "Wrz", "Paź", "Lis", "Gru"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "O kalendarzu"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "Aby pobrać najnowszÄ… wersjÄ™, odwiedź: http://www.dynarch.com/projects/calendar/\n" + "DostÄ™pny na licencji GNU LGPL. Zobacz szczegóły na http://gnu.org/licenses/lgpl.html." + "\n\n" + "Wybór daty:\n" + "- Użyj przycisków \xab, \xbb by wybrać rok\n" + "- Użyj przycisków " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " by wybrać miesiÄ…c\n" + "- Przytrzymaj klawisz myszy nad jednym z powyższych przycisków dla szybszego wyboru."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Wybór czasu:\n" + "- Kliknij na jednym z pól czasu by zwiÄ™kszyć jego wartość\n" + "- lub kliknij trzymajÄ…c Shift by zmiejszyć jego wartość\n" + "- lub kliknij i przeciÄ…gnij dla szybszego wyboru."; //Calendar._TT["TOGGLE"] = "ZmieÅ„ pierwszy dzieÅ„ tygodnia"; Calendar._TT["PREV_YEAR"] = "Poprzedni rok (przytrzymaj dla menu)"; Calendar._TT["PREV_MONTH"] = "Poprzedni miesiÄ…c (przytrzymaj dla menu)"; Calendar._TT["GO_TODAY"] = "Idź do dzisiaj"; Calendar._TT["NEXT_MONTH"] = "NastÄ™pny miesiÄ…c (przytrzymaj dla menu)"; Calendar._TT["NEXT_YEAR"] = "NastÄ™pny rok (przytrzymaj dla menu)"; Calendar._TT["SEL_DATE"] = "Wybierz datÄ™"; Calendar._TT["DRAG_TO_MOVE"] = "PrzeciÄ…gnij by przesunąć"; Calendar._TT["PART_TODAY"] = " (dzisiaj)"; Calendar._TT["MON_FIRST"] = "WyÅ›wietl poniedziaÅ‚ek jako pierwszy"; Calendar._TT["SUN_FIRST"] = "WyÅ›wietl niedzielÄ™ jako pierwszÄ…"; Calendar._TT["CLOSE"] = "Zamknij"; Calendar._TT["TODAY"] = "Dzisiaj"; Calendar._TT["TIME_PART"] = "(Shift-)Kliknij lub przeciÄ…gnij by zmienić wartość"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%e %B, %A"; Calendar._TT["WK"] = "ty"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-big5-utf8.js0000644000175000017500000000670510726351032024247 0ustar jhellstenjhellsten// ** I18N // Calendar big5-utf8 language // Author: Gary Fu, // Encoding: utf8 // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("æ—¥", "一", "二", "三", "å››", "五", "å…­", "æ—¥"); // full month names Calendar._MN = new Array ("一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "乿œˆ", "åæœˆ", "å一月", "å二月"); // short month names Calendar._SMN = new Array ("一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "乿œˆ", "åæœˆ", "å一月", "å二月"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "關於"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "æ—¥æœŸé¸æ“‡æ–¹æ³•:\n" + "- 使用 \xab, \xbb 按鈕å¯é¸æ“‡å¹´ä»½\n" + "- 使用 " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " 按鈕å¯é¸æ“‡æœˆä»½\n" + "- 按ä½ä¸Šé¢çš„æŒ‰éˆ•å¯ä»¥åŠ å¿«é¸å–"; Calendar._TT["ABOUT_TIME"] = "\n\n" + "æ™‚é–“é¸æ“‡æ–¹æ³•:\n" + "- 點擊任何的時間部份å¯å¢žåР其值\n" + "- åŒæ™‚按Shiftéµå†é»žæ“Šå¯æ¸›å°‘其值\n" + "- 點擊並拖曳å¯åŠ å¿«æ”¹è®Šçš„å€¼"; Calendar._TT["PREV_YEAR"] = "上一年 (按ä½é¸å–®)"; Calendar._TT["PREV_MONTH"] = "下一年 (按ä½é¸å–®)"; Calendar._TT["GO_TODAY"] = "到今日"; Calendar._TT["NEXT_MONTH"] = "上一月 (按ä½é¸å–®)"; Calendar._TT["NEXT_YEAR"] = "下一月 (按ä½é¸å–®)"; Calendar._TT["SEL_DATE"] = "鏿“‡æ—¥æœŸ"; Calendar._TT["DRAG_TO_MOVE"] = "拖曳"; Calendar._TT["PART_TODAY"] = " (今日)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "å°‡ %s 顯示在å‰"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "關閉"; Calendar._TT["TODAY"] = "今日"; Calendar._TT["TIME_PART"] = "點擊oræ‹–æ›³å¯æ”¹è®Šæ™‚é–“(åŒæ™‚按Shift為減)"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["WK"] = "週"; Calendar._TT["TIME"] = "Time:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-ko-utf8.js0000644000175000017500000000676010726351032024033 0ustar jhellstenjhellsten// ** I18N // Calendar EN language // Author: Mihai Bazon, // Translation: Yourim Yi // Encoding: EUC-KR // lang : ko // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("ì¼ìš”ì¼", "월요ì¼", "화요ì¼", "수요ì¼", "목요ì¼", "금요ì¼", "토요ì¼", "ì¼ìš”ì¼"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("ì¼", "ì›”", "í™”", "수", "목", "금", "토", "ì¼"); // full month names Calendar._MN = new Array ("1ì›”", "2ì›”", "3ì›”", "4ì›”", "5ì›”", "6ì›”", "7ì›”", "8ì›”", "9ì›”", "10ì›”", "11ì›”", "12ì›”"); // short month names Calendar._SMN = new Array ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "calendar ì— ëŒ€í•´ì„œ"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "\n"+ "최신 ë²„ì „ì„ ë°›ìœ¼ì‹œë ¤ë©´ http://www.dynarch.com/projects/calendar/ ì— ë°©ë¬¸í•˜ì„¸ìš”\n" + "\n"+ "GNU LGPL ë¼ì´ì„¼ìŠ¤ë¡œ ë°°í¬ë©ë‹ˆë‹¤. \n"+ "ë¼ì´ì„¼ìŠ¤ì— ëŒ€í•œ ìžì„¸í•œ ë‚´ìš©ì€ http://gnu.org/licenses/lgpl.html ì„ ì½ìœ¼ì„¸ìš”." + "\n\n" + "ë‚ ì§œ ì„ íƒ:\n" + "- ì—°ë„를 ì„ íƒí•˜ë ¤ë©´ \xab, \xbb ë²„íŠ¼ì„ ì‚¬ìš©í•©ë‹ˆë‹¤\n" + "- ë‹¬ì„ ì„ íƒí•˜ë ¤ë©´ " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " ë²„íŠ¼ì„ ëˆ„ë¥´ì„¸ìš”\n" + "- ê³„ì† ëˆ„ë¥´ê³  있으면 위 ê°’ë“¤ì„ ë¹ ë¥´ê²Œ ì„ íƒí•˜ì‹¤ 수 있습니다."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "시간 ì„ íƒ:\n" + "- 마우스로 누르면 ì‹œê°„ì´ ì¦ê°€í•©ë‹ˆë‹¤\n" + "- Shift 키와 함께 누르면 ê°ì†Œí•©ë‹ˆë‹¤\n" + "- 누른 ìƒíƒœì—서 마우스를 움ì§ì´ë©´ 좀 ë” ë¹ ë¥´ê²Œ ê°’ì´ ë³€í•©ë‹ˆë‹¤.\n"; Calendar._TT["PREV_YEAR"] = "지난 í•´ (길게 누르면 목ë¡)"; Calendar._TT["PREV_MONTH"] = "지난 달 (길게 누르면 목ë¡)"; Calendar._TT["GO_TODAY"] = "오늘 날짜로"; Calendar._TT["NEXT_MONTH"] = "ë‹¤ìŒ ë‹¬ (길게 누르면 목ë¡)"; Calendar._TT["NEXT_YEAR"] = "ë‹¤ìŒ í•´ (길게 누르면 목ë¡)"; Calendar._TT["SEL_DATE"] = "날짜를 ì„ íƒí•˜ì„¸ìš”"; Calendar._TT["DRAG_TO_MOVE"] = "마우스 드래그로 ì´ë™ 하세요"; Calendar._TT["PART_TODAY"] = " (오늘)"; Calendar._TT["MON_FIRST"] = "월요ì¼ì„ 한 ì£¼ì˜ ì‹œìž‘ ìš”ì¼ë¡œ"; Calendar._TT["SUN_FIRST"] = "ì¼ìš”ì¼ì„ 한 ì£¼ì˜ ì‹œìž‘ ìš”ì¼ë¡œ"; Calendar._TT["CLOSE"] = "닫기"; Calendar._TT["TODAY"] = "오늘"; Calendar._TT["TIME_PART"] = "(Shift-)í´ë¦­ ë˜ëŠ” 드래그 하세요"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%b/%e [%a]"; Calendar._TT["WK"] = "주"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-he-utf8.js0000644000175000017500000000751710726351032024017 0ustar jhellstenjhellsten// ** I18N // Calendar EN language // Author: Idan Sofer, // Encoding: UTF-8 // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("ר×שון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת", "ר×שון"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("×", "ב", "×’", "ד", "×”", "ו", "ש", "×"); // full month names Calendar._MN = new Array ("ינו×ר", "פברו×ר", "מרץ", "×פריל", "מ××™", "יוני", "יולי", "×וגוסט", "ספטמבר", "×וקטובר", "נובמבר", "דצמבר"); // short month names Calendar._SMN = new Array ("×™× ×", "פבר", "מרץ", "×פר", "מ××™", "יונ", "יול", "×וג", "ספט", "×וק", "נוב", "דצמ"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "×ודות השנתון"; Calendar._TT["ABOUT"] = "בחרן ת×ריך/שעה DHTML\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "×”×’×™×¨×¡× ×”×חרונה זמינה ב: http://www.dynarch.com/projects/calendar/\n" + "מופץ תחת זיכיון ×” GNU LGPL. עיין ב http://gnu.org/licenses/lgpl.html ×œ×¤×¨×˜×™× × ×•×¡×¤×™×." + "\n\n" + בחירת ת×ריך:\n" + "- השתמש ×‘×›×¤×ª×•×¨×™× \xab, \xbb לבחירת שנה\n" + "- השתמש ×‘×›×¤×ª×•×¨×™× " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " לבחירת חודש\n" + "- ×”×—×–×§ העכבר לחוץ מעל ×”×›×¤×ª×•×¨×™× ×”×ž×•×–×›×¨×™× ×œ×¢×™×œ לבחירה מהירה יותר."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "בחירת זמן:\n" + "- לחץ על כל ×חד מחלקי הזמן כדי להוסיף\n" + "- ×ו shift בשילוב ×¢× ×œ×—×™×¦×” כדי להחסיר\n" + "- ×ו לחץ וגרור לפעולה מהירה יותר."; Calendar._TT["PREV_YEAR"] = "שנה קודמת - ×”×—×–×§ לקבלת תפריט"; Calendar._TT["PREV_MONTH"] = "חודש ×§×•×“× - ×”×—×–×§ לקבלת תפריט"; Calendar._TT["GO_TODAY"] = "עבור להיו×"; Calendar._TT["NEXT_MONTH"] = "חודש ×”×‘× - ×”×—×–×§ לתפריט"; Calendar._TT["NEXT_YEAR"] = "שנה הב××” - ×”×—×–×§ לתפריט"; Calendar._TT["SEL_DATE"] = "בחר ת×ריך"; Calendar._TT["DRAG_TO_MOVE"] = "גרור להזזה"; Calendar._TT["PART_TODAY"] = " )היו×("; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "הצג %s קוד×"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "6"; Calendar._TT["CLOSE"] = "סגור"; Calendar._TT["TODAY"] = "היו×"; Calendar._TT["TIME_PART"] = "(שיפט-)לחץ וגרור כדי לשנות ערך"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["WK"] = "wk"; Calendar._TT["TIME"] = "שעה::"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-sp.js0000644000175000017500000000570710726351032023160 0ustar jhellstenjhellsten// ** I18N // Calendar SP language // Author: Rafael Velasco // Encoding: any // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Domingo", "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo"); Calendar._SDN = new Array ("Dom", "Lun", "Mar", "Mie", "Jue", "Vie", "Sab", "Dom"); // full month names Calendar._MN = new Array ("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"); // short month names Calendar._SMN = new Array ("Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Información del Calendario"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "Nuevas versiones en: http://www.dynarch.com/projects/calendar/\n" + "Distribuida bajo licencia GNU LGPL. Para detalles vea http://gnu.org/licenses/lgpl.html ." + "\n\n" + "Selección de Fechas:\n" + "- Use \xab, \xbb para seleccionar el año\n" + "- Use " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para seleccionar el mes\n" + "- Mantenga presionado el botón del ratón en cualquiera de las opciones superiores para un acceso rapido ."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Selección del Reloj:\n" + "- Seleccione la hora para cambiar el reloj\n" + "- o presione Shift-click para disminuirlo\n" + "- o presione click y arrastre del ratón para una selección rapida."; Calendar._TT["PREV_YEAR"] = "Año anterior (Presione para menu)"; Calendar._TT["PREV_MONTH"] = "Mes Anterior (Presione para menu)"; Calendar._TT["GO_TODAY"] = "Ir a Hoy"; Calendar._TT["NEXT_MONTH"] = "Mes Siguiente (Presione para menu)"; Calendar._TT["NEXT_YEAR"] = "Año Siguiente (Presione para menu)"; Calendar._TT["SEL_DATE"] = "Seleccione fecha"; Calendar._TT["DRAG_TO_MOVE"] = "Arrastre y mueva"; Calendar._TT["PART_TODAY"] = " (Hoy)"; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Mostrar %s primero"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Cerrar"; Calendar._TT["TODAY"] = "Hoy"; Calendar._TT["TIME_PART"] = "(Shift-)Click o arrastra para cambar el valor"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%dd-%mm-%yy"; Calendar._TT["TT_DATE_FORMAT"] = "%A, %e de %B de %Y"; Calendar._TT["WK"] = "Sm"; Calendar._TT["TIME"] = "Hora:"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-lt.js0000644000175000017500000000651010726351032023146 0ustar jhellstenjhellsten// ** I18N // Calendar LT language // Author: Martynas Majeris, // Encoding: Windows-1257 // Distributed under the same terms as the calendar itself. // For translators: please use UTF-8 if possible. We strongly believe that // Unicode is the answer to a real internationalized world. Also please // include your contact information in the header, as can be seen above. // full day names Calendar._DN = new Array ("Sekmadienis", "Pirmadienis", "Antradienis", "Treèiadienis", "Ketvirtadienis", "Pentadienis", "Ðeðtadienis", "Sekmadienis"); // Please note that the following array of short day names (and the same goes // for short month names, _SMN) isn't absolutely necessary. We give it here // for exemplification on how one can customize the short day names, but if // they are simply the first N letters of the full name you can simply say: // // Calendar._SDN_len = N; // short day name length // Calendar._SMN_len = N; // short month name length // // If N = 3 then this is not needed either since we assume a value of 3 if not // present, to be compatible with translation files that were written before // this feature. // short day names Calendar._SDN = new Array ("Sek", "Pir", "Ant", "Tre", "Ket", "Pen", "Ðeð", "Sek"); // full month names Calendar._MN = new Array ("Sausis", "Vasaris", "Kovas", "Balandis", "Geguþë", "Birþelis", "Liepa", "Rugpjûtis", "Rugsëjis", "Spalis", "Lapkritis", "Gruodis"); // short month names Calendar._SMN = new Array ("Sau", "Vas", "Kov", "Bal", "Geg", "Bir", "Lie", "Rgp", "Rgs", "Spa", "Lap", "Gru"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Apie kalendoriø"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "Naujausià versijà rasite: http://www.dynarch.com/projects/calendar/\n" + "Platinamas pagal GNU LGPL licencijà. Aplankykite http://gnu.org/licenses/lgpl.html" + "\n\n" + "Datos pasirinkimas:\n" + "- Metø pasirinkimas: \xab, \xbb\n" + "- Mënesio pasirinkimas: " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "\n" + "- Nuspauskite ir laikykite pelës klaviðà greitesniam pasirinkimui."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Laiko pasirinkimas:\n" + "- Spustelkite ant valandø arba minuèiø - skaièus padidës vienetu.\n" + "- Jei spausite kartu su Shift, skaièius sumaþës.\n" + "- Greitam pasirinkimui spustelkite ir pajudinkite pelæ."; Calendar._TT["PREV_YEAR"] = "Ankstesni metai (laikykite, jei norite meniu)"; Calendar._TT["PREV_MONTH"] = "Ankstesnis mënuo (laikykite, jei norite meniu)"; Calendar._TT["GO_TODAY"] = "Pasirinkti ðiandienà"; Calendar._TT["NEXT_MONTH"] = "Kitas mënuo (laikykite, jei norite meniu)"; Calendar._TT["NEXT_YEAR"] = "Kiti metai (laikykite, jei norite meniu)"; Calendar._TT["SEL_DATE"] = "Pasirinkite datà"; Calendar._TT["DRAG_TO_MOVE"] = "Tempkite"; Calendar._TT["PART_TODAY"] = " (ðiandien)"; Calendar._TT["MON_FIRST"] = "Pirma savaitës diena - pirmadienis"; Calendar._TT["SUN_FIRST"] = "Pirma savaitës diena - sekmadienis"; Calendar._TT["CLOSE"] = "Uþdaryti"; Calendar._TT["TODAY"] = "Ðiandien"; Calendar._TT["TIME_PART"] = "Spustelkite arba tempkite jei norite pakeisti"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["TT_DATE_FORMAT"] = "%A, %Y-%m-%d"; Calendar._TT["WK"] = "sav"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-el.js0000644000175000017500000000625110726351032023131 0ustar jhellstenjhellsten// ** I18N Calendar._DN = new Array ("ΚυÏιακή", "ΔευτέÏα", "ΤÏίτη", "ΤετάÏτη", "Πέμπτη", "ΠαÏασκευή", "Σάββατο", "ΚυÏιακή"); Calendar._SDN = new Array ("Κυ", "Δε", "TÏ", "Τε", "Πε", "Πα", "Σα", "Κυ"); Calendar._MN = new Array ("ΙανουάÏιος", "ΦεβÏουάÏιος", "ΜάÏτιος", "ΑπÏίλιος", "Μάϊος", "ΙοÏνιος", "ΙοÏλιος", "ΑÏγουστος", "ΣεπτέμβÏιος", "ΟκτώβÏιος", "ÎοέμβÏιος", "ΔεκέμβÏιος"); Calendar._SMN = new Array ("Ιαν", "Φεβ", "ΜαÏ", "ΑπÏ", "Μαι", "Ιουν", "Ιουλ", "Αυγ", "Σεπ", "Οκτ", "Îοε", "Δεκ"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Για το ημεÏολόγιο"; Calendar._TT["ABOUT"] = "Επιλογέας ημεÏομηνίας/ÏŽÏας σε DHTML\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "Για τελευταία έκδοση: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "Επιλογή ημεÏομηνίας:\n" + "- ΧÏησιμοποιείστε τα κουμπιά \xab, \xbb για επιλογή έτους\n" + "- ΧÏησιμοποιείστε τα κουμπιά " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " για επιλογή μήνα\n" + "- ΚÏατήστε κουμπί Ï€Î¿Î½Ï„Î¹ÎºÎ¿Ï Ï€Î±Ï„Î·Î¼Î­Î½Î¿ στα παÏαπάνω κουμπιά για πιο γÏήγοÏη επιλογή."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Επιλογή ÏŽÏας:\n" + "- Κάντε κλικ σε ένα από τα μέÏη της ÏŽÏας για αÏξηση\n" + "- ή Shift-κλικ για μείωση\n" + "- ή κλικ και μετακίνηση για πιο γÏήγοÏη επιλογή."; Calendar._TT["TOGGLE"] = "ΜπάÏα Ï€Ïώτης ημέÏας της εβδομάδας"; Calendar._TT["PREV_YEAR"] = "ΠÏοηγ. έτος (κÏατήστε για το μενοÏ)"; Calendar._TT["PREV_MONTH"] = "ΠÏοηγ. μήνας (κÏατήστε για το μενοÏ)"; Calendar._TT["GO_TODAY"] = "ΣήμεÏα"; Calendar._TT["NEXT_MONTH"] = "Επόμενος μήνας (κÏατήστε για το μενοÏ)"; Calendar._TT["NEXT_YEAR"] = "Επόμενο έτος (κÏατήστε για το μενοÏ)"; Calendar._TT["SEL_DATE"] = "Επιλέξτε ημεÏομηνία"; Calendar._TT["DRAG_TO_MOVE"] = "ΣÏÏτε για να μετακινήσετε"; Calendar._TT["PART_TODAY"] = " (σήμεÏα)"; Calendar._TT["MON_FIRST"] = "Εμφάνιση ΔευτέÏας Ï€Ïώτα"; Calendar._TT["SUN_FIRST"] = "Εμφάνιση ΚυÏιακής Ï€Ïώτα"; Calendar._TT["CLOSE"] = "Κλείσιμο"; Calendar._TT["TODAY"] = "ΣήμεÏα"; Calendar._TT["TIME_PART"] = "(Shift-)κλικ ή μετακίνηση για αλλαγή"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "dd-mm-y"; Calendar._TT["TT_DATE_FORMAT"] = "D, d M"; Calendar._TT["WK"] = "εβδ"; nurpawiki-1.2.3/files/jscalendar/lang/calendar-nl.js0000644000175000017500000000427210726351032023143 0ustar jhellstenjhellsten// ** I18N Calendar._DN = new Array ("Zondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag", "Zondag"); Calendar._SDN_len = 2; Calendar._MN = new Array ("Januari", "Februari", "Maart", "April", "Mei", "Juni", "Juli", "Augustus", "September", "Oktober", "November", "December"); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "Info"; Calendar._TT["ABOUT"] = "DHTML Datum/Tijd Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + "Ga voor de meest recente versie naar: http://www.dynarch.com/projects/calendar/\n" + "Verspreid onder de GNU LGPL. Zie http://gnu.org/licenses/lgpl.html voor details." + "\n\n" + "Datum selectie:\n" + "- Gebruik de \xab \xbb knoppen om een jaar te selecteren\n" + "- Gebruik de " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " knoppen om een maand te selecteren\n" + "- Houd de muis ingedrukt op de genoemde knoppen voor een snellere selectie."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "Tijd selectie:\n" + "- Klik op een willekeurig onderdeel van het tijd gedeelte om het te verhogen\n" + "- of Shift-klik om het te verlagen\n" + "- of klik en sleep voor een snellere selectie."; //Calendar._TT["TOGGLE"] = "Selecteer de eerste week-dag"; Calendar._TT["PREV_YEAR"] = "Vorig jaar (ingedrukt voor menu)"; Calendar._TT["PREV_MONTH"] = "Vorige maand (ingedrukt voor menu)"; Calendar._TT["GO_TODAY"] = "Ga naar Vandaag"; Calendar._TT["NEXT_MONTH"] = "Volgende maand (ingedrukt voor menu)"; Calendar._TT["NEXT_YEAR"] = "Volgend jaar (ingedrukt voor menu)"; Calendar._TT["SEL_DATE"] = "Selecteer datum"; Calendar._TT["DRAG_TO_MOVE"] = "Klik en sleep om te verplaatsen"; Calendar._TT["PART_TODAY"] = " (vandaag)"; //Calendar._TT["MON_FIRST"] = "Toon Maandag eerst"; //Calendar._TT["SUN_FIRST"] = "Toon Zondag eerst"; Calendar._TT["DAY_FIRST"] = "Toon %s eerst"; Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Sluiten"; Calendar._TT["TODAY"] = "(vandaag)"; Calendar._TT["TIME_PART"] = "(Shift-)Klik of sleep om de waarde te veranderen"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %e %b %Y"; Calendar._TT["WK"] = "wk"; Calendar._TT["TIME"] = "Tijd:";nurpawiki-1.2.3/files/jscalendar/lang/calendar-cs-utf8.js0000644000175000017500000000541010726351032024016 0ustar jhellstenjhellsten/* calendar-cs-win.js language: Czech encoding: windows-1250 author: Lubos Jerabek (xnet@seznam.cz) Jan Uhlir (espinosa@centrum.cz) */ // ** I18N Calendar._DN = new Array('NedÄ›le','PondÄ›lí','Úterý','StÅ™eda','ÄŒtvrtek','Pátek','Sobota','NedÄ›le'); Calendar._SDN = new Array('Ne','Po','Út','St','ÄŒt','Pá','So','Ne'); Calendar._MN = new Array('Leden','Únor','BÅ™ezen','Duben','KvÄ›ten','ÄŒerven','ÄŒervenec','Srpen','Září','Říjen','Listopad','Prosinec'); Calendar._SMN = new Array('Led','Úno','BÅ™e','Dub','KvÄ›','ÄŒrv','ÄŒvc','Srp','Zář','Říj','Lis','Pro'); // tooltips Calendar._TT = {}; Calendar._TT["INFO"] = "O komponentÄ› kalendář"; Calendar._TT["TOGGLE"] = "ZmÄ›na prvního dne v týdnu"; Calendar._TT["PREV_YEAR"] = "PÅ™edchozí rok (pÅ™idrž pro menu)"; Calendar._TT["PREV_MONTH"] = "PÅ™edchozí mÄ›síc (pÅ™idrž pro menu)"; Calendar._TT["GO_TODAY"] = "DneÅ¡ní datum"; Calendar._TT["NEXT_MONTH"] = "Další mÄ›síc (pÅ™idrž pro menu)"; Calendar._TT["NEXT_YEAR"] = "Další rok (pÅ™idrž pro menu)"; Calendar._TT["SEL_DATE"] = "Vyber datum"; Calendar._TT["DRAG_TO_MOVE"] = "ChyÅ¥ a táhni, pro pÅ™esun"; Calendar._TT["PART_TODAY"] = " (dnes)"; Calendar._TT["MON_FIRST"] = "Ukaž jako první PondÄ›lí"; //Calendar._TT["SUN_FIRST"] = "Ukaž jako první NedÄ›li"; Calendar._TT["ABOUT"] = "DHTML Date/Time Selector\n" + "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) "For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "VýbÄ›r datumu:\n" + "- Use the \xab, \xbb buttons to select year\n" + "- Použijte tlaÄítka " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " k výbÄ›ru mÄ›síce\n" + "- Podržte tlaÄítko myÅ¡i na jakémkoliv z tÄ›ch tlaÄítek pro rychlejší výbÄ›r."; Calendar._TT["ABOUT_TIME"] = "\n\n" + "VýbÄ›r Äasu:\n" + "- KliknÄ›te na jakoukoliv z Äástí výbÄ›ru Äasu pro zvýšení.\n" + "- nebo Shift-click pro snížení\n" + "- nebo kliknÄ›te a táhnÄ›te pro rychlejší výbÄ›r."; // the following is to inform that "%s" is to be the first day of week // %s will be replaced with the day name. Calendar._TT["DAY_FIRST"] = "Zobraz %s první"; // This may be locale-dependent. It specifies the week-end days, as an array // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 // means Monday, etc. Calendar._TT["WEEKEND"] = "0,6"; Calendar._TT["CLOSE"] = "Zavřít"; Calendar._TT["TODAY"] = "Dnes"; Calendar._TT["TIME_PART"] = "(Shift-)Klikni nebo táhni pro zmÄ›nu hodnoty"; // date formats Calendar._TT["DEF_DATE_FORMAT"] = "d.m.yy"; Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["WK"] = "wk"; Calendar._TT["TIME"] = "ÄŒas:"; nurpawiki-1.2.3/files/jscalendar/menuarrow.gif0000644000175000017500000000010410726351032022200 0ustar jhellstenjhellstenGIF89añ€€€îîæÿÿÿ!ù,¢D€%J„(Q¢D‰%J”¨;nurpawiki-1.2.3/files/jscalendar/calendar.js0000644000175000017500000014012510726351032021611 0ustar jhellstenjhellsten/* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo * ----------------------------------------------------------- * * The DHTML Calendar, version 1.0 "It is happening again" * * Details and latest version at: * www.dynarch.com/projects/calendar * * This script is developed by Dynarch.com. Visit us at www.dynarch.com. * * This script is distributed under the GNU Lesser General Public License. * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html */ // $Id: calendar.js,v 1.51 2005/03/07 16:44:31 mishoo Exp $ /** The Calendar object constructor. */ Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) { // member variables this.activeDiv = null; this.currentDateEl = null; this.getDateStatus = null; this.getDateToolTip = null; this.getDateText = null; this.timeout = null; this.onSelected = onSelected || null; this.onClose = onClose || null; this.dragging = false; this.hidden = false; this.minYear = 1970; this.maxYear = 2050; this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"]; this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"]; this.isPopup = true; this.weekNumbers = true; this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : Calendar._FD; // 0 for Sunday, 1 for Monday, etc. this.showsOtherMonths = false; this.dateStr = dateStr; this.ar_days = null; this.showsTime = false; this.time24 = true; this.yearStep = 2; this.hiliteToday = true; this.multiple = null; // HTML elements this.table = null; this.element = null; this.tbody = null; this.firstdayname = null; // Combo boxes this.monthsCombo = null; this.yearsCombo = null; this.hilitedMonth = null; this.activeMonth = null; this.hilitedYear = null; this.activeYear = null; // Information this.dateClicked = false; // one-time initializations if (typeof Calendar._SDN == "undefined") { // table of short day names if (typeof Calendar._SDN_len == "undefined") Calendar._SDN_len = 3; var ar = new Array(); for (var i = 8; i > 0;) { ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len); } Calendar._SDN = ar; // table of short month names if (typeof Calendar._SMN_len == "undefined") Calendar._SMN_len = 3; ar = new Array(); for (var i = 12; i > 0;) { ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len); } Calendar._SMN = ar; } }; // ** constants /// "static", needed for event handlers. Calendar._C = null; /// detect a special case of "web browser" Calendar.is_ie = ( /msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent) ); Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) ); /// detect Opera browser Calendar.is_opera = /opera/i.test(navigator.userAgent); /// detect KHTML-based browsers Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent); // BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate // library, at some point. Calendar.getAbsolutePos = function(el) { var SL = 0, ST = 0; var is_div = /^div$/i.test(el.tagName); if (is_div && el.scrollLeft) SL = el.scrollLeft; if (is_div && el.scrollTop) ST = el.scrollTop; var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST }; if (el.offsetParent) { var tmp = this.getAbsolutePos(el.offsetParent); r.x += tmp.x; r.y += tmp.y; } return r; }; Calendar.isRelated = function (el, evt) { var related = evt.relatedTarget; if (!related) { var type = evt.type; if (type == "mouseover") { related = evt.fromElement; } else if (type == "mouseout") { related = evt.toElement; } } while (related) { if (related == el) { return true; } related = related.parentNode; } return false; }; Calendar.removeClass = function(el, className) { if (!(el && el.className)) { return; } var cls = el.className.split(" "); var ar = new Array(); for (var i = cls.length; i > 0;) { if (cls[--i] != className) { ar[ar.length] = cls[i]; } } el.className = ar.join(" "); }; Calendar.addClass = function(el, className) { Calendar.removeClass(el, className); el.className += " " + className; }; // FIXME: the following 2 functions totally suck, are useless and should be replaced immediately. Calendar.getElement = function(ev) { var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget; while (f.nodeType != 1 || /^div$/i.test(f.tagName)) f = f.parentNode; return f; }; Calendar.getTargetElement = function(ev) { var f = Calendar.is_ie ? window.event.srcElement : ev.target; while (f.nodeType != 1) f = f.parentNode; return f; }; Calendar.stopEvent = function(ev) { ev || (ev = window.event); if (Calendar.is_ie) { ev.cancelBubble = true; ev.returnValue = false; } else { ev.preventDefault(); ev.stopPropagation(); } return false; }; Calendar.addEvent = function(el, evname, func) { if (el.attachEvent) { // IE el.attachEvent("on" + evname, func); } else if (el.addEventListener) { // Gecko / W3C el.addEventListener(evname, func, true); } else { el["on" + evname] = func; } }; Calendar.removeEvent = function(el, evname, func) { if (el.detachEvent) { // IE el.detachEvent("on" + evname, func); } else if (el.removeEventListener) { // Gecko / W3C el.removeEventListener(evname, func, true); } else { el["on" + evname] = null; } }; Calendar.createElement = function(type, parent) { var el = null; if (document.createElementNS) { // use the XHTML namespace; IE won't normally get here unless // _they_ "fix" the DOM2 implementation. el = document.createElementNS("http://www.w3.org/1999/xhtml", type); } else { el = document.createElement(type); } if (typeof parent != "undefined") { parent.appendChild(el); } return el; }; // END: UTILITY FUNCTIONS // BEGIN: CALENDAR STATIC FUNCTIONS /** Internal -- adds a set of events to make some element behave like a button. */ Calendar._add_evs = function(el) { with (Calendar) { addEvent(el, "mouseover", dayMouseOver); addEvent(el, "mousedown", dayMouseDown); addEvent(el, "mouseout", dayMouseOut); if (is_ie) { addEvent(el, "dblclick", dayMouseDblClick); el.setAttribute("unselectable", true); } } }; Calendar.findMonth = function(el) { if (typeof el.month != "undefined") { return el; } else if (typeof el.parentNode.month != "undefined") { return el.parentNode; } return null; }; Calendar.findYear = function(el) { if (typeof el.year != "undefined") { return el; } else if (typeof el.parentNode.year != "undefined") { return el.parentNode; } return null; }; Calendar.showMonthsCombo = function () { var cal = Calendar._C; if (!cal) { return false; } var cal = cal; var cd = cal.activeDiv; var mc = cal.monthsCombo; if (cal.hilitedMonth) { Calendar.removeClass(cal.hilitedMonth, "hilite"); } if (cal.activeMonth) { Calendar.removeClass(cal.activeMonth, "active"); } var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()]; Calendar.addClass(mon, "active"); cal.activeMonth = mon; var s = mc.style; s.display = "block"; if (cd.navtype < 0) s.left = cd.offsetLeft + "px"; else { var mcw = mc.offsetWidth; if (typeof mcw == "undefined") // Konqueror brain-dead techniques mcw = 50; s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px"; } s.top = (cd.offsetTop + cd.offsetHeight) + "px"; }; Calendar.showYearsCombo = function (fwd) { var cal = Calendar._C; if (!cal) { return false; } var cal = cal; var cd = cal.activeDiv; var yc = cal.yearsCombo; if (cal.hilitedYear) { Calendar.removeClass(cal.hilitedYear, "hilite"); } if (cal.activeYear) { Calendar.removeClass(cal.activeYear, "active"); } cal.activeYear = null; var Y = cal.date.getFullYear() + (fwd ? 1 : -1); var yr = yc.firstChild; var show = false; for (var i = 12; i > 0; --i) { if (Y >= cal.minYear && Y <= cal.maxYear) { yr.innerHTML = Y; yr.year = Y; yr.style.display = "block"; show = true; } else { yr.style.display = "none"; } yr = yr.nextSibling; Y += fwd ? cal.yearStep : -cal.yearStep; } if (show) { var s = yc.style; s.display = "block"; if (cd.navtype < 0) s.left = cd.offsetLeft + "px"; else { var ycw = yc.offsetWidth; if (typeof ycw == "undefined") // Konqueror brain-dead techniques ycw = 50; s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px"; } s.top = (cd.offsetTop + cd.offsetHeight) + "px"; } }; // event handlers Calendar.tableMouseUp = function(ev) { var cal = Calendar._C; if (!cal) { return false; } if (cal.timeout) { clearTimeout(cal.timeout); } var el = cal.activeDiv; if (!el) { return false; } var target = Calendar.getTargetElement(ev); ev || (ev = window.event); Calendar.removeClass(el, "active"); if (target == el || target.parentNode == el) { Calendar.cellClick(el, ev); } var mon = Calendar.findMonth(target); var date = null; if (mon) { date = new Date(cal.date); if (mon.month != date.getMonth()) { date.setMonth(mon.month); cal.setDate(date); cal.dateClicked = false; cal.callHandler(); } } else { var year = Calendar.findYear(target); if (year) { date = new Date(cal.date); if (year.year != date.getFullYear()) { date.setFullYear(year.year); cal.setDate(date); cal.dateClicked = false; cal.callHandler(); } } } with (Calendar) { removeEvent(document, "mouseup", tableMouseUp); removeEvent(document, "mouseover", tableMouseOver); removeEvent(document, "mousemove", tableMouseOver); cal._hideCombos(); _C = null; return stopEvent(ev); } }; Calendar.tableMouseOver = function (ev) { var cal = Calendar._C; if (!cal) { return; } var el = cal.activeDiv; var target = Calendar.getTargetElement(ev); if (target == el || target.parentNode == el) { Calendar.addClass(el, "hilite active"); Calendar.addClass(el.parentNode, "rowhilite"); } else { if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2))) Calendar.removeClass(el, "active"); Calendar.removeClass(el, "hilite"); Calendar.removeClass(el.parentNode, "rowhilite"); } ev || (ev = window.event); if (el.navtype == 50 && target != el) { var pos = Calendar.getAbsolutePos(el); var w = el.offsetWidth; var x = ev.clientX; var dx; var decrease = true; if (x > pos.x + w) { dx = x - pos.x - w; decrease = false; } else dx = pos.x - x; if (dx < 0) dx = 0; var range = el._range; var current = el._current; var count = Math.floor(dx / 10) % range.length; for (var i = range.length; --i >= 0;) if (range[i] == current) break; while (count-- > 0) if (decrease) { if (--i < 0) i = range.length - 1; } else if ( ++i >= range.length ) i = 0; var newval = range[i]; el.innerHTML = newval; cal.onUpdateTime(); } var mon = Calendar.findMonth(target); if (mon) { if (mon.month != cal.date.getMonth()) { if (cal.hilitedMonth) { Calendar.removeClass(cal.hilitedMonth, "hilite"); } Calendar.addClass(mon, "hilite"); cal.hilitedMonth = mon; } else if (cal.hilitedMonth) { Calendar.removeClass(cal.hilitedMonth, "hilite"); } } else { if (cal.hilitedMonth) { Calendar.removeClass(cal.hilitedMonth, "hilite"); } var year = Calendar.findYear(target); if (year) { if (year.year != cal.date.getFullYear()) { if (cal.hilitedYear) { Calendar.removeClass(cal.hilitedYear, "hilite"); } Calendar.addClass(year, "hilite"); cal.hilitedYear = year; } else if (cal.hilitedYear) { Calendar.removeClass(cal.hilitedYear, "hilite"); } } else if (cal.hilitedYear) { Calendar.removeClass(cal.hilitedYear, "hilite"); } } return Calendar.stopEvent(ev); }; Calendar.tableMouseDown = function (ev) { if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) { return Calendar.stopEvent(ev); } }; Calendar.calDragIt = function (ev) { var cal = Calendar._C; if (!(cal && cal.dragging)) { return false; } var posX; var posY; if (Calendar.is_ie) { posY = window.event.clientY + document.body.scrollTop; posX = window.event.clientX + document.body.scrollLeft; } else { posX = ev.pageX; posY = ev.pageY; } cal.hideShowCovered(); var st = cal.element.style; st.left = (posX - cal.xOffs) + "px"; st.top = (posY - cal.yOffs) + "px"; return Calendar.stopEvent(ev); }; Calendar.calDragEnd = function (ev) { var cal = Calendar._C; if (!cal) { return false; } cal.dragging = false; with (Calendar) { removeEvent(document, "mousemove", calDragIt); removeEvent(document, "mouseup", calDragEnd); tableMouseUp(ev); } cal.hideShowCovered(); }; Calendar.dayMouseDown = function(ev) { var el = Calendar.getElement(ev); if (el.disabled) { return false; } var cal = el.calendar; cal.activeDiv = el; Calendar._C = cal; if (el.navtype != 300) with (Calendar) { if (el.navtype == 50) { el._current = el.innerHTML; addEvent(document, "mousemove", tableMouseOver); } else addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver); addClass(el, "hilite active"); addEvent(document, "mouseup", tableMouseUp); } else if (cal.isPopup) { cal._dragStart(ev); } if (el.navtype == -1 || el.navtype == 1) { if (cal.timeout) clearTimeout(cal.timeout); cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250); } else if (el.navtype == -2 || el.navtype == 2) { if (cal.timeout) clearTimeout(cal.timeout); cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250); } else { cal.timeout = null; } return Calendar.stopEvent(ev); }; Calendar.dayMouseDblClick = function(ev) { Calendar.cellClick(Calendar.getElement(ev), ev || window.event); if (Calendar.is_ie) { document.selection.empty(); } }; Calendar.dayMouseOver = function(ev) { var el = Calendar.getElement(ev); if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) { return false; } if (el.ttip) { if (el.ttip.substr(0, 1) == "_") { el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1); } el.calendar.tooltips.innerHTML = el.ttip; } if (el.navtype != 300) { Calendar.addClass(el, "hilite"); if (el.caldate) { Calendar.addClass(el.parentNode, "rowhilite"); } } return Calendar.stopEvent(ev); }; Calendar.dayMouseOut = function(ev) { with (Calendar) { var el = getElement(ev); if (isRelated(el, ev) || _C || el.disabled) return false; removeClass(el, "hilite"); if (el.caldate) removeClass(el.parentNode, "rowhilite"); if (el.calendar) el.calendar.tooltips.innerHTML = _TT["SEL_DATE"]; return stopEvent(ev); } }; /** * A generic "click" handler :) handles all types of buttons defined in this * calendar. */ Calendar.cellClick = function(el, ev) { var cal = el.calendar; var closing = false; var newdate = false; var date = null; if (typeof el.navtype == "undefined") { if (cal.currentDateEl) { Calendar.removeClass(cal.currentDateEl, "selected"); Calendar.addClass(el, "selected"); closing = (cal.currentDateEl == el); if (!closing) { cal.currentDateEl = el; } } cal.date.setDateOnly(el.caldate); date = cal.date; var other_month = !(cal.dateClicked = !el.otherMonth); if (!other_month && !cal.currentDateEl) cal._toggleMultipleDate(new Date(date)); else newdate = !el.disabled; // a date was clicked if (other_month) cal._init(cal.firstDayOfWeek, date); } else { if (el.navtype == 200) { Calendar.removeClass(el, "hilite"); cal.callCloseHandler(); return; } date = new Date(cal.date); if (el.navtype == 0) date.setDateOnly(new Date()); // TODAY // unless "today" was clicked, we assume no date was clicked so // the selected handler will know not to close the calenar when // in single-click mode. // cal.dateClicked = (el.navtype == 0); cal.dateClicked = false; var year = date.getFullYear(); var mon = date.getMonth(); function setMonth(m) { var day = date.getDate(); var max = date.getMonthDays(m); if (day > max) { date.setDate(max); } date.setMonth(m); }; switch (el.navtype) { case 400: Calendar.removeClass(el, "hilite"); var text = Calendar._TT["ABOUT"]; if (typeof text != "undefined") { text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : ""; } else { // FIXME: this should be removed as soon as lang files get updated! text = "Help and about box text is not translated into this language.\n" + "If you know this language and you feel generous please update\n" + "the corresponding file in \"lang\" subdir to match calendar-en.js\n" + "and send it back to to get it into the distribution ;-)\n\n" + "Thank you!\n" + "http://dynarch.com/mishoo/calendar.epl\n"; } alert(text); return; case -2: if (year > cal.minYear) { date.setFullYear(year - 1); } break; case -1: if (mon > 0) { setMonth(mon - 1); } else if (year-- > cal.minYear) { date.setFullYear(year); setMonth(11); } break; case 1: if (mon < 11) { setMonth(mon + 1); } else if (year < cal.maxYear) { date.setFullYear(year + 1); setMonth(0); } break; case 2: if (year < cal.maxYear) { date.setFullYear(year + 1); } break; case 100: cal.setFirstDayOfWeek(el.fdow); return; case 50: var range = el._range; var current = el.innerHTML; for (var i = range.length; --i >= 0;) if (range[i] == current) break; if (ev && ev.shiftKey) { if (--i < 0) i = range.length - 1; } else if ( ++i >= range.length ) i = 0; var newval = range[i]; el.innerHTML = newval; cal.onUpdateTime(); return; case 0: // TODAY will bring us here if ((typeof cal.getDateStatus == "function") && cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) { return false; } break; } if (!date.equalsTo(cal.date)) { cal.setDate(date); newdate = true; } else if (el.navtype == 0) newdate = closing = true; } if (newdate) { ev && cal.callHandler(); } if (closing) { Calendar.removeClass(el, "hilite"); ev && cal.callCloseHandler(); } }; // END: CALENDAR STATIC FUNCTIONS // BEGIN: CALENDAR OBJECT FUNCTIONS /** * This function creates the calendar inside the given parent. If _par is * null than it creates a popup calendar inside the BODY element. If _par is * an element, be it BODY, then it creates a non-popup calendar (still * hidden). Some properties need to be set before calling this function. */ Calendar.prototype.create = function (_par) { var parent = null; if (! _par) { // default parent is the document body, in which case we create // a popup calendar. parent = document.getElementsByTagName("body")[0]; this.isPopup = true; } else { parent = _par; this.isPopup = false; } this.date = this.dateStr ? new Date(this.dateStr) : new Date(); var table = Calendar.createElement("table"); this.table = table; table.cellSpacing = 0; table.cellPadding = 0; table.calendar = this; Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown); var div = Calendar.createElement("div"); this.element = div; div.className = "calendar"; if (this.isPopup) { div.style.position = "absolute"; div.style.display = "none"; } div.appendChild(table); var thead = Calendar.createElement("thead", table); var cell = null; var row = null; var cal = this; var hh = function (text, cs, navtype) { cell = Calendar.createElement("td", row); cell.colSpan = cs; cell.className = "button"; if (navtype != 0 && Math.abs(navtype) <= 2) cell.className += " nav"; Calendar._add_evs(cell); cell.calendar = cal; cell.navtype = navtype; cell.innerHTML = "
" + text + "
"; return cell; }; row = Calendar.createElement("tr", thead); var title_length = 6; (this.isPopup) && --title_length; (this.weekNumbers) && ++title_length; hh("?", 1, 400).ttip = Calendar._TT["INFO"]; this.title = hh("", title_length, 300); this.title.className = "title"; if (this.isPopup) { this.title.ttip = Calendar._TT["DRAG_TO_MOVE"]; this.title.style.cursor = "move"; hh("×", 1, 200).ttip = Calendar._TT["CLOSE"]; } row = Calendar.createElement("tr", thead); row.className = "headrow"; this._nav_py = hh("«", 1, -2); this._nav_py.ttip = Calendar._TT["PREV_YEAR"]; this._nav_pm = hh("‹", 1, -1); this._nav_pm.ttip = Calendar._TT["PREV_MONTH"]; this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0); this._nav_now.ttip = Calendar._TT["GO_TODAY"]; this._nav_nm = hh("›", 1, 1); this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"]; this._nav_ny = hh("»", 1, 2); this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"]; // day names row = Calendar.createElement("tr", thead); row.className = "daynames"; if (this.weekNumbers) { cell = Calendar.createElement("td", row); cell.className = "name wn"; cell.innerHTML = Calendar._TT["WK"]; } for (var i = 7; i > 0; --i) { cell = Calendar.createElement("td", row); if (!i) { cell.navtype = 100; cell.calendar = this; Calendar._add_evs(cell); } } this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild; this._displayWeekdays(); var tbody = Calendar.createElement("tbody", table); this.tbody = tbody; for (i = 6; i > 0; --i) { row = Calendar.createElement("tr", tbody); if (this.weekNumbers) { cell = Calendar.createElement("td", row); } for (var j = 7; j > 0; --j) { cell = Calendar.createElement("td", row); cell.calendar = this; Calendar._add_evs(cell); } } if (this.showsTime) { row = Calendar.createElement("tr", tbody); row.className = "time"; cell = Calendar.createElement("td", row); cell.className = "time"; cell.colSpan = 2; cell.innerHTML = Calendar._TT["TIME"] || " "; cell = Calendar.createElement("td", row); cell.className = "time"; cell.colSpan = this.weekNumbers ? 4 : 3; (function(){ function makeTimePart(className, init, range_start, range_end) { var part = Calendar.createElement("span", cell); part.className = className; part.innerHTML = init; part.calendar = cal; part.ttip = Calendar._TT["TIME_PART"]; part.navtype = 50; part._range = []; if (typeof range_start != "number") part._range = range_start; else { for (var i = range_start; i <= range_end; ++i) { var txt; if (i < 10 && range_end >= 10) txt = '0' + i; else txt = '' + i; part._range[part._range.length] = txt; } } Calendar._add_evs(part); return part; }; var hrs = cal.date.getHours(); var mins = cal.date.getMinutes(); var t12 = !cal.time24; var pm = (hrs > 12); if (t12 && pm) hrs -= 12; var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23); var span = Calendar.createElement("span", cell); span.innerHTML = ":"; span.className = "colon"; var M = makeTimePart("minute", mins, 0, 59); var AP = null; cell = Calendar.createElement("td", row); cell.className = "time"; cell.colSpan = 2; if (t12) AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]); else cell.innerHTML = " "; cal.onSetTime = function() { var pm, hrs = this.date.getHours(), mins = this.date.getMinutes(); if (t12) { pm = (hrs >= 12); if (pm) hrs -= 12; if (hrs == 0) hrs = 12; AP.innerHTML = pm ? "pm" : "am"; } H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs; M.innerHTML = (mins < 10) ? ("0" + mins) : mins; }; cal.onUpdateTime = function() { var date = this.date; var h = parseInt(H.innerHTML, 10); if (t12) { if (/pm/i.test(AP.innerHTML) && h < 12) h += 12; else if (/am/i.test(AP.innerHTML) && h == 12) h = 0; } var d = date.getDate(); var m = date.getMonth(); var y = date.getFullYear(); date.setHours(h); date.setMinutes(parseInt(M.innerHTML, 10)); date.setFullYear(y); date.setMonth(m); date.setDate(d); this.dateClicked = false; this.callHandler(); }; })(); } else { this.onSetTime = this.onUpdateTime = function() {}; } var tfoot = Calendar.createElement("tfoot", table); row = Calendar.createElement("tr", tfoot); row.className = "footrow"; cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300); cell.className = "ttip"; if (this.isPopup) { cell.ttip = Calendar._TT["DRAG_TO_MOVE"]; cell.style.cursor = "move"; } this.tooltips = cell; div = Calendar.createElement("div", this.element); this.monthsCombo = div; div.className = "combo"; for (i = 0; i < Calendar._MN.length; ++i) { var mn = Calendar.createElement("div"); mn.className = Calendar.is_ie ? "label-IEfix" : "label"; mn.month = i; mn.innerHTML = Calendar._SMN[i]; div.appendChild(mn); } div = Calendar.createElement("div", this.element); this.yearsCombo = div; div.className = "combo"; for (i = 12; i > 0; --i) { var yr = Calendar.createElement("div"); yr.className = Calendar.is_ie ? "label-IEfix" : "label"; div.appendChild(yr); } this._init(this.firstDayOfWeek, this.date); parent.appendChild(this.element); }; /** keyboard navigation, only for popup calendars */ Calendar._keyEvent = function(ev) { var cal = window._dynarch_popupCalendar; if (!cal || cal.multiple) return false; (Calendar.is_ie) && (ev = window.event); var act = (Calendar.is_ie || ev.type == "keypress"), K = ev.keyCode; if (ev.ctrlKey) { switch (K) { case 37: // KEY left act && Calendar.cellClick(cal._nav_pm); break; case 38: // KEY up act && Calendar.cellClick(cal._nav_py); break; case 39: // KEY right act && Calendar.cellClick(cal._nav_nm); break; case 40: // KEY down act && Calendar.cellClick(cal._nav_ny); break; default: return false; } } else switch (K) { case 32: // KEY space (now) Calendar.cellClick(cal._nav_now); break; case 27: // KEY esc act && cal.callCloseHandler(); break; case 37: // KEY left case 38: // KEY up case 39: // KEY right case 40: // KEY down if (act) { var prev, x, y, ne, el, step; prev = K == 37 || K == 38; step = (K == 37 || K == 39) ? 1 : 7; function setVars() { el = cal.currentDateEl; var p = el.pos; x = p & 15; y = p >> 4; ne = cal.ar_days[y][x]; };setVars(); function prevMonth() { var date = new Date(cal.date); date.setDate(date.getDate() - step); cal.setDate(date); }; function nextMonth() { var date = new Date(cal.date); date.setDate(date.getDate() + step); cal.setDate(date); }; while (1) { switch (K) { case 37: // KEY left if (--x >= 0) ne = cal.ar_days[y][x]; else { x = 6; K = 38; continue; } break; case 38: // KEY up if (--y >= 0) ne = cal.ar_days[y][x]; else { prevMonth(); setVars(); } break; case 39: // KEY right if (++x < 7) ne = cal.ar_days[y][x]; else { x = 0; K = 40; continue; } break; case 40: // KEY down if (++y < cal.ar_days.length) ne = cal.ar_days[y][x]; else { nextMonth(); setVars(); } break; } break; } if (ne) { if (!ne.disabled) Calendar.cellClick(ne); else if (prev) prevMonth(); else nextMonth(); } } break; case 13: // KEY enter if (act) Calendar.cellClick(cal.currentDateEl, ev); break; default: return false; } return Calendar.stopEvent(ev); }; /** * (RE)Initializes the calendar to the given date and firstDayOfWeek */ Calendar.prototype._init = function (firstDayOfWeek, date) { var today = new Date(), TY = today.getFullYear(), TM = today.getMonth(), TD = today.getDate(); this.table.style.visibility = "hidden"; var year = date.getFullYear(); if (year < this.minYear) { year = this.minYear; date.setFullYear(year); } else if (year > this.maxYear) { year = this.maxYear; date.setFullYear(year); } this.firstDayOfWeek = firstDayOfWeek; this.date = new Date(date); var month = date.getMonth(); var mday = date.getDate(); var no_days = date.getMonthDays(); // calendar voodoo for computing the first day that would actually be // displayed in the calendar, even if it's from the previous month. // WARNING: this is magic. ;-) date.setDate(1); var day1 = (date.getDay() - this.firstDayOfWeek) % 7; if (day1 < 0) day1 += 7; date.setDate(-day1); date.setDate(date.getDate() + 1); var row = this.tbody.firstChild; var MN = Calendar._SMN[month]; var ar_days = this.ar_days = new Array(); var weekend = Calendar._TT["WEEKEND"]; var dates = this.multiple ? (this.datesCells = {}) : null; for (var i = 0; i < 6; ++i, row = row.nextSibling) { var cell = row.firstChild; if (this.weekNumbers) { cell.className = "day wn"; cell.innerHTML = date.getWeekNumber(); cell = cell.nextSibling; } row.className = "daysrow"; var hasdays = false, iday, dpos = ar_days[i] = []; for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) { iday = date.getDate(); var wday = date.getDay(); cell.className = "day"; cell.pos = i << 4 | j; dpos[j] = cell; var current_month = (date.getMonth() == month); if (!current_month) { if (this.showsOtherMonths) { cell.className += " othermonth"; cell.otherMonth = true; } else { cell.className = "emptycell"; cell.innerHTML = " "; cell.disabled = true; continue; } } else { cell.otherMonth = false; hasdays = true; } cell.disabled = false; cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday; if (dates) dates[date.print("%Y%m%d")] = cell; if (this.getDateStatus) { var status = this.getDateStatus(date, year, month, iday); if (this.getDateToolTip) { var toolTip = this.getDateToolTip(date, year, month, iday); if (toolTip) cell.title = toolTip; } if (status === true) { cell.className += " disabled"; cell.disabled = true; } else { if (/disabled/i.test(status)) cell.disabled = true; cell.className += " " + status; } } if (!cell.disabled) { cell.caldate = new Date(date); cell.ttip = "_"; if (!this.multiple && current_month && iday == mday && this.hiliteToday) { cell.className += " selected"; this.currentDateEl = cell; } if (date.getFullYear() == TY && date.getMonth() == TM && iday == TD) { cell.className += " today"; cell.ttip += Calendar._TT["PART_TODAY"]; } if (weekend.indexOf(wday.toString()) != -1) cell.className += cell.otherMonth ? " oweekend" : " weekend"; } } if (!(hasdays || this.showsOtherMonths)) row.className = "emptyrow"; } this.title.innerHTML = Calendar._MN[month] + ", " + year; this.onSetTime(); this.table.style.visibility = "visible"; this._initMultipleDates(); // PROFILE // this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms"; }; Calendar.prototype._initMultipleDates = function() { if (this.multiple) { for (var i in this.multiple) { var cell = this.datesCells[i]; var d = this.multiple[i]; if (!d) continue; if (cell) cell.className += " selected"; } } }; Calendar.prototype._toggleMultipleDate = function(date) { if (this.multiple) { var ds = date.print("%Y%m%d"); var cell = this.datesCells[ds]; if (cell) { var d = this.multiple[ds]; if (!d) { Calendar.addClass(cell, "selected"); this.multiple[ds] = date; } else { Calendar.removeClass(cell, "selected"); delete this.multiple[ds]; } } } }; Calendar.prototype.setDateToolTipHandler = function (unaryFunction) { this.getDateToolTip = unaryFunction; }; /** * Calls _init function above for going to a certain date (but only if the * date is different than the currently selected one). */ Calendar.prototype.setDate = function (date) { if (!date.equalsTo(this.date)) { this._init(this.firstDayOfWeek, date); } }; /** * Refreshes the calendar. Useful if the "disabledHandler" function is * dynamic, meaning that the list of disabled date can change at runtime. * Just * call this function if you think that the list of disabled dates * should * change. */ Calendar.prototype.refresh = function () { this._init(this.firstDayOfWeek, this.date); }; /** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */ Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) { this._init(firstDayOfWeek, this.date); this._displayWeekdays(); }; /** * Allows customization of what dates are enabled. The "unaryFunction" * parameter must be a function object that receives the date (as a JS Date * object) and returns a boolean value. If the returned value is true then * the passed date will be marked as disabled. */ Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) { this.getDateStatus = unaryFunction; }; /** Customization of allowed year range for the calendar. */ Calendar.prototype.setRange = function (a, z) { this.minYear = a; this.maxYear = z; }; /** Calls the first user handler (selectedHandler). */ Calendar.prototype.callHandler = function () { if (this.onSelected) { this.onSelected(this, this.date.print(this.dateFormat)); } }; /** Calls the second user handler (closeHandler). */ Calendar.prototype.callCloseHandler = function () { if (this.onClose) { this.onClose(this); } this.hideShowCovered(); }; /** Removes the calendar object from the DOM tree and destroys it. */ Calendar.prototype.destroy = function () { var el = this.element.parentNode; el.removeChild(this.element); Calendar._C = null; window._dynarch_popupCalendar = null; }; /** * Moves the calendar element to a different section in the DOM tree (changes * its parent). */ Calendar.prototype.reparent = function (new_parent) { var el = this.element; el.parentNode.removeChild(el); new_parent.appendChild(el); }; // This gets called when the user presses a mouse button anywhere in the // document, if the calendar is shown. If the click was outside the open // calendar this function closes it. Calendar._checkCalendar = function(ev) { var calendar = window._dynarch_popupCalendar; if (!calendar) { return false; } var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev); for (; el != null && el != calendar.element; el = el.parentNode); if (el == null) { // calls closeHandler which should hide the calendar. window._dynarch_popupCalendar.callCloseHandler(); return Calendar.stopEvent(ev); } }; /** Shows the calendar. */ Calendar.prototype.show = function () { var rows = this.table.getElementsByTagName("tr"); for (var i = rows.length; i > 0;) { var row = rows[--i]; Calendar.removeClass(row, "rowhilite"); var cells = row.getElementsByTagName("td"); for (var j = cells.length; j > 0;) { var cell = cells[--j]; Calendar.removeClass(cell, "hilite"); Calendar.removeClass(cell, "active"); } } this.element.style.display = "block"; this.hidden = false; if (this.isPopup) { window._dynarch_popupCalendar = this; Calendar.addEvent(document, "keydown", Calendar._keyEvent); Calendar.addEvent(document, "keypress", Calendar._keyEvent); Calendar.addEvent(document, "mousedown", Calendar._checkCalendar); } this.hideShowCovered(); }; /** * Hides the calendar. Also removes any "hilite" from the class of any TD * element. */ Calendar.prototype.hide = function () { if (this.isPopup) { Calendar.removeEvent(document, "keydown", Calendar._keyEvent); Calendar.removeEvent(document, "keypress", Calendar._keyEvent); Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar); } this.element.style.display = "none"; this.hidden = true; this.hideShowCovered(); }; /** * Shows the calendar at a given absolute position (beware that, depending on * the calendar element style -- position property -- this might be relative * to the parent's containing rectangle). */ Calendar.prototype.showAt = function (x, y) { var s = this.element.style; s.left = x + "px"; s.top = y + "px"; this.show(); }; /** Shows the calendar near a given element. */ Calendar.prototype.showAtElement = function (el, opts) { var self = this; var p = Calendar.getAbsolutePos(el); if (!opts || typeof opts != "string") { this.showAt(p.x, p.y + el.offsetHeight); return true; } function fixPosition(box) { if (box.x < 0) box.x = 0; if (box.y < 0) box.y = 0; var cp = document.createElement("div"); var s = cp.style; s.position = "absolute"; s.right = s.bottom = s.width = s.height = "0px"; document.body.appendChild(cp); var br = Calendar.getAbsolutePos(cp); document.body.removeChild(cp); if (Calendar.is_ie) { br.y += document.body.scrollTop; br.x += document.body.scrollLeft; } else { br.y += window.scrollY; br.x += window.scrollX; } var tmp = box.x + box.width - br.x; if (tmp > 0) box.x -= tmp; tmp = box.y + box.height - br.y; if (tmp > 0) box.y -= tmp; }; this.element.style.display = "block"; Calendar.continuation_for_the_fucking_khtml_browser = function() { var w = self.element.offsetWidth; var h = self.element.offsetHeight; self.element.style.display = "none"; var valign = opts.substr(0, 1); var halign = "l"; if (opts.length > 1) { halign = opts.substr(1, 1); } // vertical alignment switch (valign) { case "T": p.y -= h; break; case "B": p.y += el.offsetHeight; break; case "C": p.y += (el.offsetHeight - h) / 2; break; case "t": p.y += el.offsetHeight - h; break; case "b": break; // already there } // horizontal alignment switch (halign) { case "L": p.x -= w; break; case "R": p.x += el.offsetWidth; break; case "C": p.x += (el.offsetWidth - w) / 2; break; case "l": p.x += el.offsetWidth - w; break; case "r": break; // already there } p.width = w; p.height = h + 40; self.monthsCombo.style.display = "none"; fixPosition(p); self.showAt(p.x, p.y); }; if (Calendar.is_khtml) setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10); else Calendar.continuation_for_the_fucking_khtml_browser(); }; /** Customizes the date format. */ Calendar.prototype.setDateFormat = function (str) { this.dateFormat = str; }; /** Customizes the tooltip date format. */ Calendar.prototype.setTtDateFormat = function (str) { this.ttDateFormat = str; }; /** * Tries to identify the date represented in a string. If successful it also * calls this.setDate which moves the calendar to the given date. */ Calendar.prototype.parseDate = function(str, fmt) { if (!fmt) fmt = this.dateFormat; this.setDate(Date.parseDate(str, fmt)); }; Calendar.prototype.hideShowCovered = function () { if (!Calendar.is_ie && !Calendar.is_opera) return; function getVisib(obj){ var value = obj.style.visibility; if (!value) { if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C if (!Calendar.is_khtml) value = document.defaultView. getComputedStyle(obj, "").getPropertyValue("visibility"); else value = ''; } else if (obj.currentStyle) { // IE value = obj.currentStyle.visibility; } else value = ''; } return value; }; var tags = new Array("applet", "iframe", "select"); var el = this.element; var p = Calendar.getAbsolutePos(el); var EX1 = p.x; var EX2 = el.offsetWidth + EX1; var EY1 = p.y; var EY2 = el.offsetHeight + EY1; for (var k = tags.length; k > 0; ) { var ar = document.getElementsByTagName(tags[--k]); var cc = null; for (var i = ar.length; i > 0;) { cc = ar[--i]; p = Calendar.getAbsolutePos(cc); var CX1 = p.x; var CX2 = cc.offsetWidth + CX1; var CY1 = p.y; var CY2 = cc.offsetHeight + CY1; if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) { if (!cc.__msh_save_visibility) { cc.__msh_save_visibility = getVisib(cc); } cc.style.visibility = cc.__msh_save_visibility; } else { if (!cc.__msh_save_visibility) { cc.__msh_save_visibility = getVisib(cc); } cc.style.visibility = "hidden"; } } } }; /** Internal function; it displays the bar with the names of the weekday. */ Calendar.prototype._displayWeekdays = function () { var fdow = this.firstDayOfWeek; var cell = this.firstdayname; var weekend = Calendar._TT["WEEKEND"]; for (var i = 0; i < 7; ++i) { cell.className = "day name"; var realday = (i + fdow) % 7; if (i) { cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]); cell.navtype = 100; cell.calendar = this; cell.fdow = realday; Calendar._add_evs(cell); } if (weekend.indexOf(realday.toString()) != -1) { Calendar.addClass(cell, "weekend"); } cell.innerHTML = Calendar._SDN[(i + fdow) % 7]; cell = cell.nextSibling; } }; /** Internal function. Hides all combo boxes that might be displayed. */ Calendar.prototype._hideCombos = function () { this.monthsCombo.style.display = "none"; this.yearsCombo.style.display = "none"; }; /** Internal function. Starts dragging the element. */ Calendar.prototype._dragStart = function (ev) { if (this.dragging) { return; } this.dragging = true; var posX; var posY; if (Calendar.is_ie) { posY = window.event.clientY + document.body.scrollTop; posX = window.event.clientX + document.body.scrollLeft; } else { posY = ev.clientY + window.scrollY; posX = ev.clientX + window.scrollX; } var st = this.element.style; this.xOffs = posX - parseInt(st.left); this.yOffs = posY - parseInt(st.top); with (Calendar) { addEvent(document, "mousemove", calDragIt); addEvent(document, "mouseup", calDragEnd); } }; // BEGIN: DATE OBJECT PATCHES /** Adds the number of days array to the Date object. */ Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31); /** Constants used for time computations */ Date.SECOND = 1000 /* milliseconds */; Date.MINUTE = 60 * Date.SECOND; Date.HOUR = 60 * Date.MINUTE; Date.DAY = 24 * Date.HOUR; Date.WEEK = 7 * Date.DAY; Date.parseDate = function(str, fmt) { var today = new Date(); var y = 0; var m = -1; var d = 0; var a = str.split(/\W+/); var b = fmt.match(/%./g); var i = 0, j = 0; var hr = 0; var min = 0; for (i = 0; i < a.length; ++i) { if (!a[i]) continue; switch (b[i]) { case "%d": case "%e": d = parseInt(a[i], 10); break; case "%m": m = parseInt(a[i], 10) - 1; break; case "%Y": case "%y": y = parseInt(a[i], 10); (y < 100) && (y += (y > 29) ? 1900 : 2000); break; case "%b": case "%B": for (j = 0; j < 12; ++j) { if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; } } break; case "%H": case "%I": case "%k": case "%l": hr = parseInt(a[i], 10); break; case "%P": case "%p": if (/pm/i.test(a[i]) && hr < 12) hr += 12; else if (/am/i.test(a[i]) && hr >= 12) hr -= 12; break; case "%M": min = parseInt(a[i], 10); break; } } if (isNaN(y)) y = today.getFullYear(); if (isNaN(m)) m = today.getMonth(); if (isNaN(d)) d = today.getDate(); if (isNaN(hr)) hr = today.getHours(); if (isNaN(min)) min = today.getMinutes(); if (y != 0 && m != -1 && d != 0) return new Date(y, m, d, hr, min, 0); y = 0; m = -1; d = 0; for (i = 0; i < a.length; ++i) { if (a[i].search(/[a-zA-Z]+/) != -1) { var t = -1; for (j = 0; j < 12; ++j) { if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; } } if (t != -1) { if (m != -1) { d = m+1; } m = t; } } else if (parseInt(a[i], 10) <= 12 && m == -1) { m = a[i]-1; } else if (parseInt(a[i], 10) > 31 && y == 0) { y = parseInt(a[i], 10); (y < 100) && (y += (y > 29) ? 1900 : 2000); } else if (d == 0) { d = a[i]; } } if (y == 0) y = today.getFullYear(); if (m != -1 && d != 0) return new Date(y, m, d, hr, min, 0); return today; }; /** Returns the number of days in the current month */ Date.prototype.getMonthDays = function(month) { var year = this.getFullYear(); if (typeof month == "undefined") { month = this.getMonth(); } if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) { return 29; } else { return Date._MD[month]; } }; /** Returns the number of day in the year. */ Date.prototype.getDayOfYear = function() { var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0); var time = now - then; return Math.floor(time / Date.DAY); }; /** Returns the number of the week in year, as defined in ISO 8601. */ Date.prototype.getWeekNumber = function() { var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); var DoW = d.getDay(); d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu var ms = d.valueOf(); // GMT d.setMonth(0); d.setDate(4); // Thu in Week 1 return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1; }; /** Checks date and time equality */ Date.prototype.equalsTo = function(date) { return ((this.getFullYear() == date.getFullYear()) && (this.getMonth() == date.getMonth()) && (this.getDate() == date.getDate()) && (this.getHours() == date.getHours()) && (this.getMinutes() == date.getMinutes())); }; /** Set only the year, month, date parts (keep existing time) */ Date.prototype.setDateOnly = function(date) { var tmp = new Date(date); this.setDate(1); this.setFullYear(tmp.getFullYear()); this.setMonth(tmp.getMonth()); this.setDate(tmp.getDate()); }; /** Prints the date in a string according to the given format. */ Date.prototype.print = function (str) { var m = this.getMonth(); var d = this.getDate(); var y = this.getFullYear(); var wn = this.getWeekNumber(); var w = this.getDay(); var s = {}; var hr = this.getHours(); var pm = (hr >= 12); var ir = (pm) ? (hr - 12) : hr; var dy = this.getDayOfYear(); if (ir == 0) ir = 12; var min = this.getMinutes(); var sec = this.getSeconds(); s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N] s["%A"] = Calendar._DN[w]; // full weekday name s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N] s["%B"] = Calendar._MN[m]; // full month name // FIXME: %c : preferred date and time representation for the current locale s["%C"] = 1 + Math.floor(y / 100); // the century number s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31) s["%e"] = d; // the day of the month (range 1 to 31) // FIXME: %D : american date style: %m/%d/%y // FIXME: %E, %F, %G, %g, %h (man strftime) s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format) s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format) s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366) s["%k"] = hr; // hour, range 0 to 23 (24h format) s["%l"] = ir; // hour, range 1 to 12 (12h format) s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12 s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59 s["%n"] = "\n"; // a newline character s["%p"] = pm ? "PM" : "AM"; s["%P"] = pm ? "pm" : "am"; // FIXME: %r : the time in am/pm notation %I:%M:%S %p // FIXME: %R : the time in 24-hour notation %H:%M s["%s"] = Math.floor(this.getTime() / 1000); s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59 s["%t"] = "\t"; // a tab character // FIXME: %T : the time in 24-hour notation (%H:%M:%S) s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn; s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON) s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN) // FIXME: %x : preferred date representation for the current locale without the time // FIXME: %X : preferred time representation for the current locale without the date s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99) s["%Y"] = y; // year with the century s["%%"] = "%"; // a literal '%' character var re = /%./g; if (!Calendar.is_ie5 && !Calendar.is_khtml) return str.replace(re, function (par) { return s[par] || par; }); var a = str.match(re); for (var i = 0; i < a.length; i++) { var tmp = s[a[i]]; if (tmp) { re = new RegExp(a[i], 'g'); str = str.replace(re, tmp); } } return str; }; Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear; Date.prototype.setFullYear = function(y) { var d = new Date(this); d.__msh_oldSetFullYear(y); if (d.getMonth() != this.getMonth()) this.setDate(28); this.__msh_oldSetFullYear(y); }; // END: DATE OBJECT PATCHES // global object that remembers the calendar window._dynarch_popupCalendar = null; nurpawiki-1.2.3/files/jscalendar/calendar-blue2.css0000644000175000017500000001161610726351032022776 0ustar jhellstenjhellsten/* The main calendar widget. DIV containing a table. */ div.calendar { position: relative; } .calendar, .calendar table { border: 1px solid #206A9B; font-size: 11px; color: #000; cursor: default; background: #F1F8FC; font-family: tahoma,verdana,sans-serif; } /* Header part -- contains navigation buttons and day names. */ .calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ text-align: center; /* They are the navigation buttons */ padding: 2px; /* Make the buttons seem like they're pressing */ } .calendar .nav { background: #007ED1 url(menuarrow2.gif) no-repeat 100% 100%; } .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; /* Pressing it will take you to the current date */ text-align: center; background: #000; color: #fff; padding: 2px; } .calendar thead tr { /* Row containing navigation buttons */ background: #007ED1; color: #fff; } .calendar thead .daynames { /* Row containing the day names */ background: #C7E1F3; } .calendar thead .name { /* Cells containing the day names */ border-bottom: 1px solid #206A9B; padding: 2px; text-align: center; color: #000; } .calendar thead .weekend { /* How a weekend day name shows in header */ color: #a66; } .calendar thead .hilite { /* How do the buttons in header appear when hover */ background-color: #34ABFA; color: #000; border: 1px solid #016DC5; padding: 1px; } .calendar thead .active { /* Active (pressed) buttons in header */ background-color: #006AA9; border: 1px solid #008AFF; padding: 2px 0px 0px 2px; } /* The body part -- contains all the days in month. */ .calendar tbody .day { /* Cells containing month days dates */ width: 2em; color: #456; text-align: right; padding: 2px 4px 2px 2px; } .calendar tbody .day.othermonth { font-size: 80%; color: #bbb; } .calendar tbody .day.othermonth.oweekend { color: #fbb; } .calendar table .wn { padding: 2px 3px 2px 2px; border-right: 1px solid #000; background: #C7E1F3; } .calendar tbody .rowhilite td { background: #def; } .calendar tbody .rowhilite td.wn { background: #F1F8FC; } .calendar tbody td.hilite { /* Hovered cells */ background: #def; padding: 1px 3px 1px 1px; border: 1px solid #8FC4E8; } .calendar tbody td.active { /* Active (pressed) cells */ background: #cde; padding: 2px 2px 0px 2px; } .calendar tbody td.selected { /* Cell showing today date */ font-weight: bold; border: 1px solid #000; padding: 1px 3px 1px 1px; background: #fff; color: #000; } .calendar tbody td.weekend { /* Cells showing weekend days */ color: #a66; } .calendar tbody td.today { /* Cell showing selected date */ font-weight: bold; color: #D50000; } .calendar tbody .disabled { color: #999; } .calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ visibility: hidden; } .calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ display: none; } /* The footer part -- status bar and "Close" button */ .calendar tfoot .footrow { /* The in footer (only one right now) */ text-align: center; background: #206A9B; color: #fff; } .calendar tfoot .ttip { /* Tooltip (status bar) cell */ background: #000; color: #fff; border-top: 1px solid #206A9B; padding: 1px; } .calendar tfoot .hilite { /* Hover style for buttons in footer */ background: #B8DAF0; border: 1px solid #178AEB; color: #000; padding: 1px; } .calendar tfoot .active { /* Active (pressed) style for buttons in footer */ background: #006AA9; padding: 2px 0px 0px 2px; } /* Combo boxes (menus that display months/years for direct selection) */ .calendar .combo { position: absolute; display: none; top: 0px; left: 0px; width: 4em; cursor: default; border: 1px solid #655; background: #def; color: #000; font-size: 90%; z-index: 100; } .calendar .combo .label, .calendar .combo .label-IEfix { text-align: center; padding: 1px; } .calendar .combo .label-IEfix { width: 4em; } .calendar .combo .hilite { background: #34ABFA; border-top: 1px solid #46a; border-bottom: 1px solid #46a; font-weight: bold; } .calendar .combo .active { border-top: 1px solid #46a; border-bottom: 1px solid #46a; background: #F1F8FC; font-weight: bold; } .calendar td.time { border-top: 1px solid #000; padding: 1px 0px; text-align: center; background-color: #E3F0F9; } .calendar td.time .hour, .calendar td.time .minute, .calendar td.time .ampm { padding: 0px 3px 0px 4px; border: 1px solid #889; font-weight: bold; background-color: #F1F8FC; } .calendar td.time .ampm { text-align: center; } .calendar td.time .colon { padding: 0px 2px 0px 3px; font-weight: bold; } .calendar td.time span.hilite { border-color: #000; background-color: #267DB7; color: #fff; } .calendar td.time span.active { border-color: red; background-color: #000; color: #A5FF00; } nurpawiki-1.2.3/files/jscalendar/calendar-blue.css0000644000175000017500000001133610726351032022713 0ustar jhellstenjhellsten/* The main calendar widget. DIV containing a table. */ div.calendar { position: relative; } .calendar, .calendar table { border: 1px solid #556; font-size: 11px; color: #000; cursor: default; background: #eef; font-family: tahoma,verdana,sans-serif; } /* Header part -- contains navigation buttons and day names. */ .calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ text-align: center; /* They are the navigation buttons */ padding: 2px; /* Make the buttons seem like they're pressing */ } .calendar .nav { background: #778 url(menuarrow.gif) no-repeat 100% 100%; } .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; /* Pressing it will take you to the current date */ text-align: center; background: #fff; color: #000; padding: 2px; } .calendar thead .headrow { /* Row containing navigation buttons */ background: #778; color: #fff; } .calendar thead .daynames { /* Row containing the day names */ background: #bdf; } .calendar thead .name { /* Cells containing the day names */ border-bottom: 1px solid #556; padding: 2px; text-align: center; color: #000; } .calendar thead .weekend { /* How a weekend day name shows in header */ color: #a66; } .calendar thead .hilite { /* How do the buttons in header appear when hover */ background-color: #aaf; color: #000; border: 1px solid #04f; padding: 1px; } .calendar thead .active { /* Active (pressed) buttons in header */ background-color: #77c; padding: 2px 0px 0px 2px; } /* The body part -- contains all the days in month. */ .calendar tbody .day { /* Cells containing month days dates */ width: 2em; color: #456; text-align: right; padding: 2px 4px 2px 2px; } .calendar tbody .day.othermonth { font-size: 80%; color: #bbb; } .calendar tbody .day.othermonth.oweekend { color: #fbb; } .calendar table .wn { padding: 2px 3px 2px 2px; border-right: 1px solid #000; background: #bdf; } .calendar tbody .rowhilite td { background: #def; } .calendar tbody .rowhilite td.wn { background: #eef; } .calendar tbody td.hilite { /* Hovered cells */ background: #def; padding: 1px 3px 1px 1px; border: 1px solid #bbb; } .calendar tbody td.active { /* Active (pressed) cells */ background: #cde; padding: 2px 2px 0px 2px; } .calendar tbody td.selected { /* Cell showing today date */ font-weight: bold; border: 1px solid #000; padding: 1px 3px 1px 1px; background: #fff; color: #000; } .calendar tbody td.weekend { /* Cells showing weekend days */ color: #a66; } .calendar tbody td.today { /* Cell showing selected date */ font-weight: bold; color: #00f; } .calendar tbody .disabled { color: #999; } .calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ visibility: hidden; } .calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ display: none; } /* The footer part -- status bar and "Close" button */ .calendar tfoot .footrow { /* The in footer (only one right now) */ text-align: center; background: #556; color: #fff; } .calendar tfoot .ttip { /* Tooltip (status bar) cell */ background: #fff; color: #445; border-top: 1px solid #556; padding: 1px; } .calendar tfoot .hilite { /* Hover style for buttons in footer */ background: #aaf; border: 1px solid #04f; color: #000; padding: 1px; } .calendar tfoot .active { /* Active (pressed) style for buttons in footer */ background: #77c; padding: 2px 0px 0px 2px; } /* Combo boxes (menus that display months/years for direct selection) */ .calendar .combo { position: absolute; display: none; top: 0px; left: 0px; width: 4em; cursor: default; border: 1px solid #655; background: #def; color: #000; font-size: 90%; z-index: 100; } .calendar .combo .label, .calendar .combo .label-IEfix { text-align: center; padding: 1px; } .calendar .combo .label-IEfix { width: 4em; } .calendar .combo .hilite { background: #acf; } .calendar .combo .active { border-top: 1px solid #46a; border-bottom: 1px solid #46a; background: #eef; font-weight: bold; } .calendar td.time { border-top: 1px solid #000; padding: 1px 0px; text-align: center; background-color: #f4f0e8; } .calendar td.time .hour, .calendar td.time .minute, .calendar td.time .ampm { padding: 0px 3px 0px 4px; border: 1px solid #889; font-weight: bold; background-color: #fff; } .calendar td.time .ampm { text-align: center; } .calendar td.time .colon { padding: 0px 2px 0px 3px; font-weight: bold; } .calendar td.time span.hilite { border-color: #000; background-color: #667; color: #fff; } .calendar td.time span.active { border-color: #f00; background-color: #000; color: #0f0; } nurpawiki-1.2.3/files/jscalendar/calendar-win2k-cold-1.css0000644000175000017500000001322610726351032024073 0ustar jhellstenjhellsten/* The main calendar widget. DIV containing a table. */ .calendar { position: relative; display: none; border-top: 2px solid #fff; border-right: 2px solid #000; border-bottom: 2px solid #000; border-left: 2px solid #fff; font-size: 11px; color: #000; cursor: default; background: #c8d0d4; font-family: tahoma,verdana,sans-serif; } .calendar table { border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; font-size: 11px; color: #000; cursor: default; background: #c8d0d4; font-family: tahoma,verdana,sans-serif; } /* Header part -- contains navigation buttons and day names. */ .calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ text-align: center; padding: 1px; border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; } .calendar .nav { background: transparent url(menuarrow.gif) no-repeat 100% 100%; } .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; padding: 1px; border: 1px solid #000; background: #788084; color: #fff; text-align: center; } .calendar thead .headrow { /* Row containing navigation buttons */ } .calendar thead .daynames { /* Row containing the day names */ } .calendar thead .name { /* Cells containing the day names */ border-bottom: 1px solid #000; padding: 2px; text-align: center; background: #e8f0f4; } .calendar thead .weekend { /* How a weekend day name shows in header */ color: #f00; } .calendar thead .hilite { /* How do the buttons in header appear when hover */ border-top: 2px solid #fff; border-right: 2px solid #000; border-bottom: 2px solid #000; border-left: 2px solid #fff; padding: 0px; background-color: #d8e0e4; } .calendar thead .active { /* Active (pressed) buttons in header */ padding: 2px 0px 0px 2px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; background-color: #b8c0c4; } /* The body part -- contains all the days in month. */ .calendar tbody .day { /* Cells containing month days dates */ width: 2em; text-align: right; padding: 2px 4px 2px 2px; } .calendar tbody .day.othermonth { font-size: 80%; color: #aaa; } .calendar tbody .day.othermonth.oweekend { color: #faa; } .calendar table .wn { padding: 2px 3px 2px 2px; border-right: 1px solid #000; background: #e8f4f0; } .calendar tbody .rowhilite td { background: #d8e4e0; } .calendar tbody .rowhilite td.wn { background: #c8d4d0; } .calendar tbody td.hilite { /* Hovered cells */ padding: 1px 3px 1px 1px; border: 1px solid; border-color: #fff #000 #000 #fff; } .calendar tbody td.active { /* Active (pressed) cells */ padding: 2px 2px 0px 2px; border: 1px solid; border-color: #000 #fff #fff #000; } .calendar tbody td.selected { /* Cell showing selected date */ font-weight: bold; padding: 2px 2px 0px 2px; border: 1px solid; border-color: #000 #fff #fff #000; background: #d8e0e4; } .calendar tbody td.weekend { /* Cells showing weekend days */ color: #f00; } .calendar tbody td.today { /* Cell showing today date */ font-weight: bold; color: #00f; } .calendar tbody .disabled { color: #999; } .calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ visibility: hidden; } .calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ display: none; } /* The footer part -- status bar and "Close" button */ .calendar tfoot .footrow { /* The in footer (only one right now) */ } .calendar tfoot .ttip { /* Tooltip (status bar) cell */ background: #e8f0f4; padding: 1px; border: 1px solid #000; background: #788084; color: #fff; text-align: center; } .calendar tfoot .hilite { /* Hover style for buttons in footer */ border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; padding: 1px; background: #d8e0e4; } .calendar tfoot .active { /* Active (pressed) style for buttons in footer */ padding: 2px 0px 0px 2px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; } /* Combo boxes (menus that display months/years for direct selection) */ .calendar .combo { position: absolute; display: none; width: 4em; top: 0px; left: 0px; cursor: default; border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; background: #d8e0e4; font-size: 90%; padding: 1px; z-index: 100; } .calendar .combo .label, .calendar .combo .label-IEfix { text-align: center; padding: 1px; } .calendar .combo .label-IEfix { width: 4em; } .calendar .combo .active { background: #c8d0d4; padding: 0px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; } .calendar .combo .hilite { background: #048; color: #aef; } .calendar td.time { border-top: 1px solid #000; padding: 1px 0px; text-align: center; background-color: #e8f0f4; } .calendar td.time .hour, .calendar td.time .minute, .calendar td.time .ampm { padding: 0px 3px 0px 4px; border: 1px solid #889; font-weight: bold; background-color: #fff; } .calendar td.time .ampm { text-align: center; } .calendar td.time .colon { padding: 0px 2px 0px 3px; font-weight: bold; } .calendar td.time span.hilite { border-color: #000; background-color: #667; color: #fff; } .calendar td.time span.active { border-color: #f00; background-color: #000; color: #0f0; } nurpawiki-1.2.3/files/jscalendar/calendar-setup_stripped.js0000644000175000017500000001146710726351032024667 0ustar jhellstenjhellsten/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ * --------------------------------------------------------------------------- * * The DHTML Calendar * * Details and latest version at: * http://dynarch.com/mishoo/calendar.epl * * This script is distributed under the GNU Lesser General Public License. * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html * * This file defines helper functions for setting up the calendar. They are * intended to help non-programmers get a working calendar on their site * quickly. This script should not be seen as part of the calendar. It just * shows you what one can do with the calendar, while in the same time * providing a quick and simple method for setting it up. If you need * exhaustive customization of the calendar creation process feel free to * modify this code to suit your needs (this is recommended and much better * than modifying calendar.js itself). */ Calendar.setup=function(params){function param_default(pname,def){if(typeof params[pname]=="undefined"){params[pname]=def;}};param_default("inputField",null);param_default("displayArea",null);param_default("button",null);param_default("eventName","click");param_default("ifFormat","%Y/%m/%d");param_default("daFormat","%Y/%m/%d");param_default("singleClick",true);param_default("disableFunc",null);param_default("dateStatusFunc",params["disableFunc"]);param_default("dateText",null);param_default("firstDay",null);param_default("align","Br");param_default("range",[1900,2999]);param_default("weekNumbers",true);param_default("flat",null);param_default("flatCallback",null);param_default("onSelect",null);param_default("onClose",null);param_default("onUpdate",null);param_default("date",null);param_default("showsTime",false);param_default("timeFormat","24");param_default("electric",true);param_default("step",2);param_default("position",null);param_default("cache",false);param_default("showOthers",false);param_default("multiple",null);var tmp=["inputField","displayArea","button"];for(var i in tmp){if(typeof params[tmp[i]]=="string"){params[tmp[i]]=document.getElementById(params[tmp[i]]);}}if(!(params.flat||params.multiple||params.inputField||params.displayArea||params.button)){alert("Calendar.setup:\n Nothing to setup (no fields found). Please check your code");return false;}function onSelect(cal){var p=cal.params;var update=(cal.dateClicked||p.electric);if(update&&p.inputField){p.inputField.value=cal.date.print(p.ifFormat);if(typeof p.inputField.onchange=="function")p.inputField.onchange();}if(update&&p.displayArea)p.displayArea.innerHTML=cal.date.print(p.daFormat);if(update&&typeof p.onUpdate=="function")p.onUpdate(cal);if(update&&p.flat){if(typeof p.flatCallback=="function")p.flatCallback(cal);}if(update&&p.singleClick&&cal.dateClicked)cal.callCloseHandler();};if(params.flat!=null){if(typeof params.flat=="string")params.flat=document.getElementById(params.flat);if(!params.flat){alert("Calendar.setup:\n Flat specified but can't find parent.");return false;}var cal=new Calendar(params.firstDay,params.date,params.onSelect||onSelect);cal.showsOtherMonths=params.showOthers;cal.showsTime=params.showsTime;cal.time24=(params.timeFormat=="24");cal.params=params;cal.weekNumbers=params.weekNumbers;cal.setRange(params.range[0],params.range[1]);cal.setDateStatusHandler(params.dateStatusFunc);cal.getDateText=params.dateText;if(params.ifFormat){cal.setDateFormat(params.ifFormat);}if(params.inputField&&typeof params.inputField.value=="string"){cal.parseDate(params.inputField.value);}cal.create(params.flat);cal.show();return false;}var triggerEl=params.button||params.displayArea||params.inputField;triggerEl["on"+params.eventName]=function(){var dateEl=params.inputField||params.displayArea;var dateFmt=params.inputField?params.ifFormat:params.daFormat;var mustCreate=false;var cal=window.calendar;if(dateEl)params.date=Date.parseDate(dateEl.value||dateEl.innerHTML,dateFmt);if(!(cal&¶ms.cache)){window.calendar=cal=new Calendar(params.firstDay,params.date,params.onSelect||onSelect,params.onClose||function(cal){cal.hide();});cal.showsTime=params.showsTime;cal.time24=(params.timeFormat=="24");cal.weekNumbers=params.weekNumbers;mustCreate=true;}else{if(params.date)cal.setDate(params.date);cal.hide();}if(params.multiple){cal.multiple={};for(var i=params.multiple.length;--i>=0;){var d=params.multiple[i];var ds=d.print("%Y%m%d");cal.multiple[ds]=d;}}cal.showsOtherMonths=params.showOthers;cal.yearStep=params.step;cal.setRange(params.range[0],params.range[1]);cal.params=params;cal.setDateStatusHandler(params.dateStatusFunc);cal.getDateText=params.dateText;cal.setDateFormat(dateFmt);if(mustCreate)cal.create();cal.refresh();if(!params.position)cal.showAtElement(params.button||params.displayArea||params.inputField,params.align);else cal.showAt(params.position[0],params.position[1]);return false;};return cal;};nurpawiki-1.2.3/files/jscalendar/README0000644000175000017500000000161610726351032020363 0ustar jhellstenjhellstenThe DHTML Calendar ------------------- Author: Mihai Bazon, http://dynarch.com/mishoo/ This program is free software published under the terms of the GNU Lesser General Public License. For the entire license text please refer to http://www.gnu.org/licenses/lgpl.html Contents --------- calendar.js -- the main program file lang/*.js -- internalization files *.css -- color themes cal.html -- example usage file doc/ -- documentation, in PDF and HTML simple-1.html -- quick setup examples [popup calendars] simple-2.html -- quick setup example for flat calendar calendar.php -- PHP wrapper test.php -- test file for the PHP wrapper Homepage --------- For details and latest versions please refer to calendar homepage, located on my website: http://dynarch.com/mishoo/calendar.epl nurpawiki-1.2.3/files/jscalendar/calendar-brown.css0000644000175000017500000001115410726351032023111 0ustar jhellstenjhellsten/* The main calendar widget. DIV containing a table. */ div.calendar { position: relative; } .calendar, .calendar table { border: 1px solid #655; font-size: 11px; color: #000; cursor: default; background: #ffd; font-family: tahoma,verdana,sans-serif; } /* Header part -- contains navigation buttons and day names. */ .calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ text-align: center; /* They are the navigation buttons */ padding: 2px; /* Make the buttons seem like they're pressing */ } .calendar .nav { background: #edc url(menuarrow.gif) no-repeat 100% 100%; } .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; /* Pressing it will take you to the current date */ text-align: center; background: #654; color: #fed; padding: 2px; } .calendar thead .headrow { /* Row containing navigation buttons */ background: #edc; color: #000; } .calendar thead .name { /* Cells containing the day names */ border-bottom: 1px solid #655; padding: 2px; text-align: center; color: #000; } .calendar thead .weekend { /* How a weekend day name shows in header */ color: #f00; } .calendar thead .hilite { /* How do the buttons in header appear when hover */ background-color: #faa; color: #000; border: 1px solid #f40; padding: 1px; } .calendar thead .active { /* Active (pressed) buttons in header */ background-color: #c77; padding: 2px 0px 0px 2px; } .calendar thead .daynames { /* Row containing the day names */ background: #fed; } /* The body part -- contains all the days in month. */ .calendar tbody .day { /* Cells containing month days dates */ width: 2em; text-align: right; padding: 2px 4px 2px 2px; } .calendar tbody .day.othermonth { font-size: 80%; color: #bbb; } .calendar tbody .day.othermonth.oweekend { color: #fbb; } .calendar table .wn { padding: 2px 3px 2px 2px; border-right: 1px solid #000; background: #fed; } .calendar tbody .rowhilite td { background: #ddf; } .calendar tbody .rowhilite td.wn { background: #efe; } .calendar tbody td.hilite { /* Hovered cells */ background: #ffe; padding: 1px 3px 1px 1px; border: 1px solid #bbb; } .calendar tbody td.active { /* Active (pressed) cells */ background: #ddc; padding: 2px 2px 0px 2px; } .calendar tbody td.selected { /* Cell showing today date */ font-weight: bold; border: 1px solid #000; padding: 1px 3px 1px 1px; background: #fea; } .calendar tbody td.weekend { /* Cells showing weekend days */ color: #f00; } .calendar tbody td.today { font-weight: bold; } .calendar tbody .disabled { color: #999; } .calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ visibility: hidden; } .calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ display: none; } /* The footer part -- status bar and "Close" button */ .calendar tfoot .footrow { /* The in footer (only one right now) */ text-align: center; background: #988; color: #000; } .calendar tfoot .ttip { /* Tooltip (status bar) cell */ border-top: 1px solid #655; background: #dcb; color: #840; } .calendar tfoot .hilite { /* Hover style for buttons in footer */ background: #faa; border: 1px solid #f40; padding: 1px; } .calendar tfoot .active { /* Active (pressed) style for buttons in footer */ background: #c77; padding: 2px 0px 0px 2px; } /* Combo boxes (menus that display months/years for direct selection) */ .calendar .combo { position: absolute; display: none; top: 0px; left: 0px; width: 4em; cursor: default; border: 1px solid #655; background: #ffe; color: #000; font-size: 90%; z-index: 100; } .calendar .combo .label, .calendar .combo .label-IEfix { text-align: center; padding: 1px; } .calendar .combo .label-IEfix { width: 4em; } .calendar .combo .hilite { background: #fc8; } .calendar .combo .active { border-top: 1px solid #a64; border-bottom: 1px solid #a64; background: #fee; font-weight: bold; } .calendar td.time { border-top: 1px solid #a88; padding: 1px 0px; text-align: center; background-color: #fed; } .calendar td.time .hour, .calendar td.time .minute, .calendar td.time .ampm { padding: 0px 3px 0px 4px; border: 1px solid #988; font-weight: bold; background-color: #fff; } .calendar td.time .ampm { text-align: center; } .calendar td.time .colon { padding: 0px 2px 0px 3px; font-weight: bold; } .calendar td.time span.hilite { border-color: #000; background-color: #866; color: #fff; } .calendar td.time span.active { border-color: #f00; background-color: #000; color: #0f0; } nurpawiki-1.2.3/files/jscalendar/calendar-win2k-cold-2.css0000644000175000017500000001354210726351032024075 0ustar jhellstenjhellsten/* The main calendar widget. DIV containing a table. */ .calendar { position: relative; display: none; border-top: 2px solid #fff; border-right: 2px solid #000; border-bottom: 2px solid #000; border-left: 2px solid #fff; font-size: 11px; color: #000; cursor: default; background: #c8d4d0; font-family: tahoma,verdana,sans-serif; } .calendar table { border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; font-size: 11px; color: #000; cursor: default; background: #c8d4d0; font-family: tahoma,verdana,sans-serif; } /* Header part -- contains navigation buttons and day names. */ .calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ text-align: center; padding: 1px; border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; } .calendar .nav { background: transparent url(menuarrow.gif) no-repeat 100% 100%; } .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; padding: 1px; border: 1px solid #000; background: #788480; color: #fff; text-align: center; } .calendar thead .headrow { /* Row containing navigation buttons */ } .calendar thead .daynames { /* Row containing the day names */ } .calendar thead .name { /* Cells containing the day names */ border-bottom: 1px solid #000; padding: 2px; text-align: center; background: #e8f4f0; } .calendar thead .weekend { /* How a weekend day name shows in header */ color: #f00; } .calendar thead .hilite { /* How do the buttons in header appear when hover */ border-top: 2px solid #fff; border-right: 2px solid #000; border-bottom: 2px solid #000; border-left: 2px solid #fff; padding: 0px; background-color: #d8e4e0; } .calendar thead .active { /* Active (pressed) buttons in header */ padding: 2px 0px 0px 2px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; background-color: #b8c4c0; } /* The body part -- contains all the days in month. */ .calendar tbody .day { /* Cells containing month days dates */ width: 2em; text-align: right; padding: 2px 4px 2px 2px; } .calendar tbody .day.othermonth { font-size: 80%; color: #aaa; } .calendar tbody .day.othermonth.oweekend { color: #faa; } .calendar table .wn { padding: 2px 3px 2px 2px; border-right: 1px solid #000; background: #e8f4f0; } .calendar tbody .rowhilite td { background: #d8e4e0; } .calendar tbody .rowhilite td.wn { background: #c8d4d0; } .calendar tbody td.hilite { /* Hovered cells */ padding: 1px 3px 1px 1px; border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; } .calendar tbody td.active { /* Active (pressed) cells */ padding: 2px 2px 0px 2px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; } .calendar tbody td.selected { /* Cell showing selected date */ font-weight: bold; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; padding: 2px 2px 0px 2px; background: #d8e4e0; } .calendar tbody td.weekend { /* Cells showing weekend days */ color: #f00; } .calendar tbody td.today { /* Cell showing today date */ font-weight: bold; color: #00f; } .calendar tbody .disabled { color: #999; } .calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ visibility: hidden; } .calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ display: none; } /* The footer part -- status bar and "Close" button */ .calendar tfoot .footrow { /* The in footer (only one right now) */ } .calendar tfoot .ttip { /* Tooltip (status bar) cell */ background: #e8f4f0; padding: 1px; border: 1px solid #000; background: #788480; color: #fff; text-align: center; } .calendar tfoot .hilite { /* Hover style for buttons in footer */ border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; padding: 1px; background: #d8e4e0; } .calendar tfoot .active { /* Active (pressed) style for buttons in footer */ padding: 2px 0px 0px 2px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; } /* Combo boxes (menus that display months/years for direct selection) */ .calendar .combo { position: absolute; display: none; width: 4em; top: 0px; left: 0px; cursor: default; border-top: 1px solid #fff; border-right: 1px solid #000; border-bottom: 1px solid #000; border-left: 1px solid #fff; background: #d8e4e0; font-size: 90%; padding: 1px; z-index: 100; } .calendar .combo .label, .calendar .combo .label-IEfix { text-align: center; padding: 1px; } .calendar .combo .label-IEfix { width: 4em; } .calendar .combo .active { background: #c8d4d0; padding: 0px; border-top: 1px solid #000; border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; } .calendar .combo .hilite { background: #048; color: #aef; } .calendar td.time { border-top: 1px solid #000; padding: 1px 0px; text-align: center; background-color: #e8f0f4; } .calendar td.time .hour, .calendar td.time .minute, .calendar td.time .ampm { padding: 0px 3px 0px 4px; border: 1px solid #889; font-weight: bold; background-color: #fff; } .calendar td.time .ampm { text-align: center; } .calendar td.time .colon { padding: 0px 2px 0px 3px; font-weight: bold; } .calendar td.time span.hilite { border-color: #000; background-color: #667; color: #fff; } .calendar td.time span.active { border-color: #f00; background-color: #000; color: #0f0; } nurpawiki-1.2.3/files/style.css0000644000175000017500000001004511070736137017251 0ustar jhellstenjhellstenbody { font-family: Verdana,Geneva,Arial,Sans-serif; font-size: 12px; background-color : #FFFFFF } img { border: 0px none; } a:visited { color : #000080; ; text-decoration : underline; } a:link { color : #2222FF; ; text-decoration : underline; } a:hover { text-decoration : none; } a.cancel_edit { color : Red; font-weight:bold; } a.wiki_pri_lo { background-color: #ada; } a.wiki_pri_med { background-color: #dda; } a.wiki_pri_hi { background-color: #daa; } a.missing_page:visited { color : Red; text-decoration : underline; } a.missing_page:link { color : Red; text-decoration : underline; } a.missing_page:hover { color : Red; text-decoration : none; } /* Accesskey'd links -- first letter underlined */ a.ak { text-decoration: underline; } a.ak:hover { color:#2222FF; text-decoration: none;} a.ak:focus { color:#2222FF; text-decoration: none;} a.ak:first-letter { color:#2222FF; text-decoration: none; font-weight:bold; } a.palette0 { color:rgb(128, 6, 25); } a.palette1 { color:rgb(0, 104, 28); } a.palette2 { color:rgb(0, 148, 145); } a.palette3 { color:rgb(91, 16, 148); } a.palette4 { color:rgb(170, 107, 0); } a.palette5 { color:rgb(211, 0, 96); } a.palette6 { color:rgb(0, 91, 105); } a.palette7 { color:rgb(185, 0, 56); } a.palette8 { color:rgb(0, 98, 84); } a.palette9 { color:rgb(0, 104, 53); } a.palette10 { color:rgb(132, 102, 0); } a.palette11 { color:rgb(51, 0, 153); } .no_break { white-space:nowrap; } /* TODO items */ .todo_descr { color:#222; font-size : smaller; } .todo_descr_completed { color:#777; text-decoration : line-through; font-size: smaller; } .todo_pri_lo { background-color: #cfc; } .todo_pri_med { background-color: #ffc; } .todo_pri_hi { background-color: #fcc; } .todo_table_completed { text-decoration : line-through; color:#555; } .todo_table { font-size : smaller; } .todo_priority_changed { font-weight: bold; } .todo_completed_row { background-color:#ddd; } .rm_odd_row { background-color:#ddf; } .rm_even_row { background-color:#bbe; } .rm_table_heading { color:#777; font-size:smaller; text-align:right; font-style:italic; } .rm_edit { text-align:right; } .h_date_heading { color:#777; text-align:right; font-style:italic; } .act_date_input { text-align: center; background-color: #ccc; } .scheduler_check_button { font-size: 0.75em; } .error { color : Red; font-weight:bold; } .todo_owner { color : #558; } /* Search results */ .sr_link { font-size: 1.15em; } .sr_hilite { background-color: #ff9; } code { color : #000070 } pre { color : #000070 } h4.entry { text-decoration: underline } h1 { text-align: left; color:#AF4040; } h1.left_aligned { text-align: left; } h4 { margin-bottom:0px; margin-top:0px; } h2 {color:#BF3030; } html, body { margin: 0; padding: 0; } .top_menu_size { width:100%; } .top_menu_left_align { text-align: left; vertical-align: bottom; padding: 5px; } .top_menu_right_align { text-align: right; vertical-align: bottom; padding: 5px; } #login_outer { height:100%; } #login_align_middle { position:absolute; top: 35%; left: 30%; text-align:left; padding: 5px; } .login_text { font-weight:bold; color:#fff; } .login_text_descr { color:#fff; } table.login_box { background-color:#77c; padding: 5px; border: 3px solid #99f; } .login_link_big { font-size:1.2em; font-weight:bold; } .action_bar { padding-left:10px; padding-right:10px; padding-top:3px; padding-bottom:3px; background-color:#ff9; color:#000; } .undo_link { color:#338; } #topbar { margin-top:5px; margin-left:10px; margin-right:10px; float:top; height:50px; border-bottom: 2px solid #ccf; } #top_action_bar { margin-top:5px; margin-left:10px; margin-right:10px; margin-bottom:5px; float:top; height:10px;; background-color:#fff; padding:10px; text-align:center; font-weight:bold; } #navbar { width: 300px; float: left; margin-left: 0px; margin-top: 2px; padding: 12px; } #content { padding: 5px; margin-left: 400px; } a#login_help_url { color : Black; font-weight:bold; } nurpawiki-1.2.3/files/calendar.png0000644000175000017500000000467310667075457017704 0ustar jhellstenjhellsten‰PNG  IHDRä߯iCCPICC Profilexœ—iXSgÇÿ7a4("Ê"²»YD@@@C HL‚Rqi•±N‹vlUì 8Uœ¢Ž#KE‹uDDTt@Q {Ì|¸IÀéûéÜ÷9ç=÷üçÜç½€v+K(äS¤¤JDáþÞŒè˜X†ZèA ãàÀb‹…^¡¡ÁsõÕ€;v,¡s´¾ö¡ÅoqמÏô¬-¡ä ‹¢cb€Ai/`@Ú ÖI„€H`ÀNfq" €­("œ …èI¤] €ž@ÚWÐÓÙI€¨¨ú©^* ÒÐ<8\1дÀáˆÙ)€f.@¼MIpí\Öl¡Hh—°‹Ž‰e¯p½hÄŒì §ò«®‘=+`T<Ùë€0ª':9-o@õ±LÖm¨í†wÉdƒ2Ùða€ÚüÊg§‰ÒåzÄMàsÏdÍòE%U•¦®¡©E×ÑÓ70š`bjf>‰a1ÕÒjºõL[ûYŽNήnîsæÍ_àáéåÍôñõ_´8dIhXxDdÔ²è˜åq+VƯb%°9ÜĤdÞê5ü”Tp­H,IK_—‘¹~CÖ³7mÞ²õ˯¶mÏÉùÓŽ¯wþù›oswíþî/{¾ÿaïÞ}ûóüø×üƒ‡ þÛOGŽû{Ññü\\|â䩞þ×™’Ò²²ò_ÎVœ;ÿkeå…ß.^º|åêÕk×ÿ}ãæ­[UÕ·kîÜ©½[w¯¾þþƒ‡ ÿ§±±éÉÓæægÏ[ZZ_´½|Ùþª££óµTÚÕÝÝÓÛ××?0ðû›7ƒCCÃÃoe ªÐÔÔ54µ´utõÆ›L43ŸÌ°˜j9ÍÊzÆL[;ûY³œ]ÜÜçÌ·ÀÃs¡ÓÇ×Ï? 0(˜Ô`iDdÔ²èØÑ"|Vƒ÷%+ðPÁX ”+ @Ö_U}»æNmíݺ{õ÷<ü øm/ÛÛ_utv¾–vuu÷(ªW–ÿV UE•¦¦®1NSK›N×ÑÕÓ?ÞÀÐh‚±‰©éD3óI“S¦Lµœf5ÝzÆL[;ûY³œ]\ÝÜÜçÌ7‡çB/o¦¯¯Ÿÿ"R¹,dsÄÄ.[±beü*+ÍáŽîwä!õy¿Iä}J£QýröÜù+4"PcÓ“æg-/^¾zÝÝ÷û° gh®Àc *c9Û€΀Q!ª DÌee)(Kâ@d„JTР ]aìá†Åˆ›‘‹|T¢ÏM‚A¸A‹È% ‰J¢—¢C±¡p(ù” JÕŒº€O=L½LmSqVÉV9¢rSÕ\U¨º_õ"m"MB;D«R³SÛ©V¡Ö¡®^ªÁÐˆÐØ¡Ñ7Ž3¿æfͳZŽZEÚVÚÚMt ú!Kcº³tź¥zL½*ýúã7¿n`hPdÈ4|d”9aÂ„Ä gŒ£‡L™.2•N<``6`^8iùdÉ—_X¸YtM91U`é`Ù=­Äjãt?k]ë†ÇffÚÚšÙJí®Øœ•é9ÛÉQß±Ûé®s™ËA×ínkÝãæÌuŸg½€îAõôìYØáÕæÝÊlõyáÛî'õï_$ Ô2¶Y¸$<41lCøî¥E—"›¢dÑ“b<—W´¢fåàªi¬ð„lv1§1Q?É?9kõ+¾u 'µ@дvŠˆ+>&éLw͸¶Þp;ëÔFjvä¦c›e_oÓØÎ͹°ÃâëÍ;Ÿ~{|—þî ß5ï ýþì¾¼<­Ù?öä¯.ˆ=|÷§°#U…!EaÇkŽ-n<ÕuzãÍ’}åågW4_wáèE¯K®™\/¿±ü¦ìv`´6ïžô~þÃÇ'9O«Ÿå´xµ•µ§wöKËz½ûÕßì;[&#¿­ *;`„>N RIŸEä•Ä¢—bCñ§p(ù”ÊÕìò7UzUÍU…ªU;iiZ•šZœÚÎ?Îýêræ&=Ÿ ®óǹÏ7ýùŲñŒeÅžwzõ«÷Ù¯Ëθ¶Þp„ýÖ¨wéã?šÿ^›uÀ±[Š8É;ÕuF³d_ÙŒòòЦóë*é#=Puøv`´Î÷žô~~ƒìñÉ'&O«[¼Z‡ÚÓ;û»³z½ª‡¸2™’¾‚=IžäîBä•D/ņ¡4ÈY·©8«d“”•ŒwÊùŽÐU²E–ä:UÓE¦Ò‰¾CSÉRARÁQAñã Ç"8Ö쎦ǷMd7zr·Fýoì6}„žyqãI9Ãe3S\I'çøÊÅ$“kóH’CdO6rž˜<­~–óœÓâÕ:ÔVöò‡öô×N£Îþ×÷¤e]û»³zâ{½{ï÷ ûÕû¸TÿÎ{C¼Ù?è4xcˆ;T?4|îíl™±L÷EÀ8¦€/1‚™>Ÿ¹Üþ¿+…Ÿ¦È¡@‹' ˆ`àb¢È/€7€úÔ„%ô”+ö]*·my~tÂC( ` !ë“#– DâjV`¨Ü–¤òC‚Ä×ÇW»w (€@rS#矧/Uø\æ°|‚˜DÝúdfˆÜ¿ Á` °!ˆÀÃ5°! ©`  °!bHÀB2À<¬Exà€ ±<> |p‘üÀ‚IàÂNžáÑp3$À3E¼¤d ÃK(äsLAŠ0MÂÙ2RÙö¶ Gø/TÆ‘z®H ÇIDAT8푱 Â0EOlw§R¡ÿ ğ芓»øEݺˆ£S3¥‹P⨤U¬&Bï’¼¼¼Ã½‰0ÆJlË¡Ó(âÖ4Ì×+¤”moâ㨨5õq @Y–a çkÕ{C»`€ØxÙvòt<ü y:ëcìï«—ÃBgèݽì'Iò¥ß‡´ÖH)ÝøY–µ{¥ÔàZAUUm/Èïwå8UJáS?…Žñ1þ úãÿÖ©Ö:ôÒ‡–ÝàiAIEND®B`‚nurpawiki-1.2.3/files/nurpawiki_scheduler.js0000644000175000017500000000133510733332020021772 0ustar jhellstenjhellsten function nwSetButtonCheckedState(v) { var inputs = document.getElementsByTagName("input"); var re = new RegExp("^t-([0-9]+)$"); for (var i = 0; i < inputs.length; i++) { var m = re.exec(inputs[i].name); if (m != null) { inputs[i].checked = v; } } } function nwSelectAllButton() { nwSetButtonCheckedState(true); } function nwDeselectAllButton() { nwSetButtonCheckedState(false); } function nwRegisterSchedulerButtons() { var b = document.getElementById("button_select_all"); b.onclick = nwSelectAllButton; var b = document.getElementById("button_deselect_all"); b.onclick = nwDeselectAllButton; } addLoadEvent(nwRegisterSchedulerButtons); nurpawiki-1.2.3/files/nurpawiki_calendar.js0000644000175000017500000000147710733332020021574 0ustar jhellstenjhellsten // Register jscalendar selectors for cal_trigger named buttons. Each // cal_trigger named button has an id of form 'button_' where // is the todo's DB id. For each such element, there should exist a // 'calendar_' element that contains the date to be edited. function nwRegisterCalendar() { cals = document.getElementsByTagName("button"); re = new RegExp("^cal_button_([0-9]+)$"); for (var i = 0; i < cals.length; i++) { var m = re.exec(cals[i].id); if (m != null) { var todo_id = m[1]; Calendar.setup( { inputField : "calendar_"+todo_id, ifFormat : "%Y-%m-%d", button : m[0] } ); } } } addLoadEvent(nwRegisterCalendar); nurpawiki-1.2.3/files/arrow_down.png0000644000175000017500000000667610667075457020321 0ustar jhellstenjhellsten‰PNG  IHDR &Îàq âiCCPICC Profilexœ­—y8Ô]Ç¿c_“}„ˆH²V–±d_²o5f#cÆJ EQIËÓ®’VÒÓª¢´kQJmH©h#Q„š÷Ôóö<ïû\ïrþºÏ¹îûÜç÷û|®ë\í¢r8‰XIí_׈Üаp€` @>n4v 3_ÀãðB<yZ<•0æPB)bÜh\ €3ß@L£ÅñÂ#@„”Dg&¢ï‘YtF  ÓSh,€¸ |g±Øt@v€I4—ÈV0 '9Ê °hDŸþ\ã '‡ÌŸkzË%O ´îçZ_Šõ)±ÓÌ)'@¸ÏïÓD7ßÖóùÃ{øüo{ÁàR"-•›6ö¿„;ÀßÍG¿yl@@H`@HXXXDBTXLR\LBZRLJBZ–(-##K”“%ÉN ɓ䕔”•UTUÕÔTÕ5444µÈšÚ:::ººõô&êëN62661™bjjj6Õ|ê4 ‹é––VV6¶¶¶vv3fΜ9k¦½½£““…âLqqqu=ÛÝÝÃÝÓËËËÇÛ××ÏÏ? `N``PPpHHHhhxxDDddTttô¼yTjL N§3qqññLfsþüD‹Åæp8É\.7…Ëã¥òÒÒ.L_¸hQFÆâÅK–dffeeg/]º,'7gyîŠyyùù+W®ZµzuAÁš5……k×®[·~ý† ¿ý¶qã¦M›7oÙ²uë¶mÛ·íØ±sç®]ÅÅ»w—”ìÙ³wï¾}û÷Ð;pààÁÒÒ²²C‡ÊËþý÷#GŽ=vìøñ'Nž¬¨8eqêÔéÓgÎTVVU={î\uõùó.\¼xÉþҥ˗¯\¹zµ¦æÚµë×oܸy³vvmí­[·o×Õݹs×ûîÝúú{÷îßoðohhl|ð ©©9¨¹ùáÃG?~öäÉÓ§--­­mQmmÏžµ·?þâEGLGÇË—¯^½~ÝÙÙ×ÕõæÍÛ·ïÞ½ÿáC7«»»§çãÇÞÞOŸú¸}}ýýŸ?ù2008øõëPúÐÐððÈÈ·oß¿ó3ùüQþ‚!!aq!Q 1Qq) QIq)i)"QFZVFN†$7AN~‚‚¢¢’’‚²ŠŠªªŠšººº†¦¦†™LÖÖÖÑÕÕÑÓÓ×7Пd`8ÉÈhòdcS33Ó©æææÓÌ-,¦O·²¶¶¶±±µ³³›a7s¦½ƒƒƒ££“#…âììââæ:ÛÍÝÃÃÃÓÃËËÇÇ×ÏÏßß? 0(((88$$44,,<"2"**:zîÜyT*•F£ÓŒØØ¸ØøxfBBB"‹ÅJb³Ùvr279%eÔ‚ ÒÓ± {Ù²œœÜÜåËÿg~Z`ô—ŒZ`õ'þh˘ãxݹó†ƀ1 þì@Û³gísÇ7 ¶³óŸ èîIúaÀ8ÿ´1~áOX&ÀtRê>'²R4Rlª¸¨x“D‰$WÊEZ^ºƒxJ&WÖ_NS®›T5!O>TÁ@¡Oñ¼Rž²¿ŠªJ»ê!µTu{ a[škµ‚ÈäíC:l]3݉Uz‹ôgè7¸:)×ÐÅHʨnòco1“Ú)ù¦.fBfצ.7§LS˜öÁâÊôÍ–‰VÖrÖ6§lóìÂfL™)6³eÖ û•ÑŽfNpj ”:/qqwÕpíq«™½Í}¾‡­§¬g›×ïÞY>^¾*¾oý*ýs|ç¨Íé <”ì"r?tKؼp£ðO§#F͈ˆ¾67žUŽz7f5Í›.Mod”ÆnŽ[¿š™‘:?1‘Ú—ÁváX'suR&ð„yƒ©i ªîO߸('ƒ½Øg‰UæÄ,©¬žìK«—çdæÆ/Ÿ½Â(O&ïS~ãÊŠU›W§D®±+Ô(ü¶¶eÝ…õ%ò~coôÝdº™´ypKÛÖ ÛvnÏ.ŠÛá¿Óv—f±`qÿîþ’¡=Ã{¿ìëßÿñ@ÏÁ®Òö²ŽC­å×ý^säÂÑÊc'=qøä¡Š²Se§ËÏ©¼^Uw¶ñÜ“êÎ „‹ —Ì.»_I¼º©æòµžZ7ýjóo5ÔéÞI»[wÏðþöFÒƒõÍú¯>ŽjÐ*ÐÖÕÞÝ¡ò*¶³ùíÚk{‰ŸYÚ|>0z÷€ˆ%°Å¾’€Uf€A9 X øI6Ðvƒ€Ü;\4Çï I(BVðKQŒËxE$L'P ë— Ÿ& ЊZÕç î|+d!”%tGXCØU˜#\#¢&©5-íÓ «'‹¯ÿ"A—h’t“\*Y-e.U.­/½‡¨M¤Kd&ʔɚÊVÊQäêIФ(R÷„lyùrŠÂ:…VÅt%%¥Óʡʇ”GTJTg«öªíPëSwWÔ(ՌВÑJкF^¢m¥ýI瘮Œ.{¢ÙÄ>½3ú™®å“d'µ–¥Oö0V7î5‰4¹1e·iºYÐÔiæ$ó¾iMnUÓw[æY%[GÚ¸ÛZÛMš¡:“8KpVÖ¬aû~‡nÇ·N]”.ç7.ï]{Ýfó=Ä=å½´½Í||übý36Ì)¼ô<˜ªfNXYÕ=ewËý„m?Î<ñé´ä™mU†gÏž~qÁe╃5Ž72jUn­‹¸Ã¿ïÑÐû ¨Ùåaïãâ~Ûñvú •Ž{Ž]#o«Þ§u[ö ôV}v¼7´}„ÁçÿàÿßÐÿ#ûHÑÑî_Ø%Ýþö­Š“°Q)Qée¯î®>¨á7Æ~œ¼¿Î±Ÿäõ_¸þ-ù1îV¯!ÿàN;ú+ù?r_õGòãÜóÿŽüÎþâ„=á{›öû²?ü`œ}EæiÉ*óg«½Gé×8^kýkúO}Zø£ô_åóïè­ê[ü @$èÂAHÅ6\F7L$n H ø  t Ú¾r*f ·Šx‰\µ=%f)V%î ~K"J¢[2_JOªFšA”!ž’aÈ*É6Ê­&yO™Ð ¿K!LQF±^i²¿ŠªÊ+Õ“j¹êA:Ú÷´ÊÉÚ\]›‰ÆzÊúúƒÝ“Þ¾0z3ùqß˜Š›iMµ4÷–`±~ú ËçÖr6޶»Òïf™Ø'9œsäSœOºŠ»ÅÍ®poòøà9ä­îcáëïGõ_P:§5H$xjHDèú°+ბ–QéÑWç R]cÖÒ>0ìbWÄu0ŠæóYó“np¬“÷¥Hó–¥.HZر(2£mIxæólÆÒΜØÜ—+RóW¬&,tXû`=mC÷ƬÍZ[Žm›¸½°hhç¢]½»SJÞíåìãH;ø½¬°\ëð±#ŽGÓO|©È;­ræP•ÝÙÛÕçë.†]꺲 FèÚ‚ëÃ7¹µ=·êšîÚ×—Þ—iHklirlÞõ°ó±é“´§Õ­„6—géíûŸ×¿øúRýÕÔ×Î!]ño’ßrÞÑÞÏùàÐmÒ#Õóîcuoá§à>µ¾§ý›>û|þò¥xÀiàé ï«ð×¼!‰¡5CCÃŒáúÛ‘M#/¿Y|ËùÖø]÷ûÊïýü¹üZ>}/$(ìD6—ìEqþ›ÇÝ:X‰©ã=dH1yîäÔÄr]8x”ãã €T).sÆbãX¦«;Y€0‹Ãó   |ņ „ت‡ßXÌKJôñ –ÑÎ.cµ[ç³=H„RFRÐøþ)isÆs®Ó©ÎžÔBó¢xŠÏXþ'xgA‰`ƒ &jAT$ŒvAL¤€*R±d$‚‰d¤‚ :H«OE"H® ‚‹80`2ÖáÏ}‚ñ\0ÿMt°ç2—qY'bÓ¶²ÓmƒãÍÊÍÞ˜€<–íù£#I?ví3>¿ûþÌû”»“d¿q¿œÃ± ‚‹40‚ùx .Xs™Ë~Öaôí "²ÀŽ`¸8˜‘ý«'<ÆBPØœt.3.žGväpd ›ÅIå1¸Æd÷$Úc²¹™Ùtøý£x/ëû—IDAT•cüÿÿ?^À„_š…aË–-===˜r555...L †††Xu›˜˜ l)¯(G“niiAØ"--ýçï_4ºººüüüH.ýÿ¿ªª .ì,%//ÿÉ555>>>¸f(¸{÷î¡Cííí/\¸ðñãG¸8 \Ÿ’’77„ÁËË‹pÑTðùóg4äXË” •IEND®B`‚nurpawiki-1.2.3/files/nurpawiki.js0000644000175000017500000000045710667075457017770 0ustar jhellstenjhellsten function addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { if (oldonload) { oldonload(); } func(); } } } nurpawiki-1.2.3/files/edit_small.png0000644000175000017500000000457010667075457020244 0ustar jhellstenjhellsten‰PNG  IHDR &Îàq¯iCCPICC Profilexœ—iXSgÇÿ7a4("Ê"²»YD@@@C HL‚Rqi•±N‹vlUì 8Uœ¢Ž#KE‹uDDTt@Q {Ì|¸IÀéûéÜ÷9ç=÷üçÜç½€v+K(äS¤¤JDáþÞŒè˜X†ZèA ãàÀb‹…^¡¡ÁsõÕ€;v,¡s´¾ö¡ÅoqמÏô¬-¡ä ‹¢cb€Ai/`@Ú ÖI„€H`ÀNfq" €­("œ …èI¤] €ž@ÚWÐÓÙI€¨¨ú©^* ÒÐ<8\1дÀáˆÙ)€f.@¼MIpí\Öl¡Hh—°‹Ž‰e¯p½hÄŒì §ò«®‘=+`T<Ùë€0ª':9-o@õ±LÖm¨í†wÉdƒ2Ùða€ÚüÊg§‰ÒåzÄMàsÏdÍòE%U•¦®¡©E×ÑÓ70š`bjf>‰a1ÕÒjºõL[ûYŽNήnîsæÍ_àáéåÍôñõ_´8dIhXxDdÔ²è˜åq+VƯb%°9ÜĤdÞê5ü”Tp­H,IK_—‘¹~CÖ³7mÞ²õ˯¶mÏÉùÓŽ¯wþù›oswíþî/{¾ÿaïÞ}ûóüø×üƒ‡ þÛOGŽû{Ññü\\|â䩞þ×™’Ò²²ò_ÎVœ;ÿkeå…ß.^º|åêÕk×ÿ}ãæ­[UÕ·kîÜ©½[w¯¾þþƒ‡ ÿ§±±éÉÓæægÏ[ZZ_´½|Ùþª££óµTÚÕÝÝÓÛ××?0ðû›7ƒCCÃÃoe ªÐÔÔ54µ´utõÆ›L43ŸÌ°˜j9ÍÊzÆL[;ûY³œ]ÜÜçÌ·ÀÃs¡ÓÇ×Ï? 0(˜Ô`iDdÔ²èØÑ"|Vƒ÷%+ðPÁX ”+ @Ö_U}»æNmíݺ{õ÷<ü øm/ÛÛ_utv¾–vuu÷(ªW–ÿV UE•¦¦®1NSK›N×ÑÕÓ?ÞÀÐh‚±‰©éD3óI“S¦Lµœf5ÝzÆL[;ûY³œ]\ÝÜÜçÌ7‡çB/o¦¯¯Ÿÿ"R¹,dsÄÄ.[±beü*+ÍáŽîwä!õy¿Iä}J£QýröÜù+4"PcÓ“æg-/^¾zÝÝ÷û° gh®Àc *c9Û€΀Q!ª DÌee)(Kâ@d„JTР ]aìá†Åˆ›‘‹|T¢ÏM‚A¸A‹È% ‰J¢—¢C±¡p(ù” JÕŒº€O=L½LmSqVÉV9¢rSÕ\U¨º_õ"m"MB;D«R³SÛ©V¡Ö¡®^ªÁÐˆÐØ¡Ñ7Ž3¿æfͳZŽZEÚVÚÚMt ú!Kcº³tź¥zL½*ýúã7¿n`hPdÈ4|d”9aÂ„Ä gŒ£‡L™.2•N<``6`^8iùdÉ—_X¸YtM91U`é`Ù=­Äjãt?k]ë†ÇffÚÚšÙJí®Øœ•é9ÛÉQß±Ûé®s™ËA×ínkÝãæÌuŸg½€îAõôìYØáÕæÝÊlõyáÛî'õï_$ Ô2¶Y¸$<41lCøî¥E—"›¢dÑ“b<—W´¢fåàªi¬ð„lv1§1Q?É?9kõ+¾u 'µ@дvŠˆ+>&éLw͸¶Þp;ëÔFjvä¦c›e_oÓØÎ͹°ÃâëÍ;Ÿ~{|—þî ß5ï ýþì¾¼<­Ù?öä¯.ˆ=|÷§°#U…!EaÇkŽ-n<ÕuzãÍ’}åågW4_wáèE¯K®™\/¿±ü¦ìv`´6ïžô~þÃÇ'9O«Ÿå´xµ•µ§wöKËz½ûÕßì;[&#¿­ *;`„>N RIŸEä•Ä¢—bCñ§p(ù”ÊÕìò7UzUÍU…ªU;iiZ•šZœÚÎ?Îýêræ&=Ÿ ®óǹÏ7ýùŲñŒeÅžwzõ«÷Ù¯Ëθ¶Þp„ýÖ¨wéã?šÿ^›uÀ±[Š8É;ÕuF³d_ÙŒòòЦóë*é#=Puøv`´Î÷žô~~ƒìñÉ'&O«[¼Z‡ÚÓ;û»³z½ª‡¸2™’¾‚=IžäîBä•D/ņ¡4ÈY·©8«d“”•ŒwÊùŽÐU²E–ä:UÓE¦Ò‰¾CSÉRARÁQAñã Ç"8Ö쎦ǷMd7zr·Fýoì6}„žyqãI9Ãe3S\I'çøÊÅ$“kóH’CdO6rž˜<­~–óœÓâÕ:ÔVöò‡öô×N£Îþ×÷¤e]û»³zâ{½{ï÷ ûÕû¸TÿÎ{C¼Ù?è4xcˆ;T?4|îíl™±L÷EÀ8¦€/1‚™>Ÿ¹Üþ¿+…Ÿ¦È¡@‹' ˆ`àb¢È/€7€úÔ„%ô”+ö]*·my~tÂC( ` !ë“#– DâjV`¨Ü–¤òC‚Ä×ÇW»w (€@rS#矧/Uø\æ°|‚˜DÝúdfˆÜ¿ Á` °!ˆÀÃ5°! ©`  °!bHÀB2À<¬Exà€ ±<> |p‘üÀ‚IàÂNžáÑp3$À3E¼¤d ÃK(äsLAŠ0MÂÙ2RÙö¶ Gø/TÆ‘z®H „IDAT•± Ã0 ߆{ ¢’…+Ž Z›pnÂV+¨Ö0š€.˜(‚8ùêñ÷ AnîŽ[DäVÕ=Ü™³ªž9‡ h¿_ñWcsw™s~²”’ª˜¹÷^k%¢`c 3cæÇ-¥f€ˆŽþTkmÍo­­üÕX¥wìîÛÏŸ^ÅF]îoÁcIEND®B`‚nurpawiki-1.2.3/files/external_link.png0000644000175000017500000000023610667075457020761 0ustar jhellstenjhellsten‰PNG  IHDR s;eIDAT™Mޱ „0ÄLDÃD›d(Ã$¡1£|ŠŸ€A¾ñ7p}ò¹‘‡€ €‚jYT³ ó5® À¶u)ÖùL)Ö¾u?˯€ƒ~²ƒj ã}:ÞÍ;ç^&Ìšó*»IEND®B`‚nurpawiki-1.2.3/files/home.png0000644000175000017500000000275311070641437017042 0ustar jhellstenjhellsten‰PNG  IHDR—p ngAMA±Ž|ûQ“ cHRMz%€ƒùÿ€èu0ê`:—o—©™ÔvIDATxœbøÿÿ?à K @ ¢í}èÿ+çþÿ 0‡c.Ëÿ¿¢ÿ˜ÃÄàxPí秈ÿ@}òÄððîÿÿ÷oýÿ`ÏËÿW’å^ÀþÆ 0!³’ïÙ#×ÿG®Üÿ÷ÜëÿG¾ý@p{·|ûãê7¸€B±ÔÅß{¾Fƒ\°&@ A®º—¾ÿ;>†ÿÝ’@ Á +²òïØÿ/}ìþÿʼ ÿÜþ– †øˆýIüÿïæÿÿ‹WÇÿñ"@`ó«Îÿzúðÿ ¢…0;Õ%3åÖƒíbql® dÅ o‚ÀŽ…Èõf{”A13L@ Æ™ ÿóïØý/†ÈG 8‘^%øÿþŒ¸ÿ?íû÷Æÿÿì³8Ašm¬ä‘Oþÿ_ÆóäSî¹Üÿo]zlvìÿÿ7Êÿ?{ôÿÿ©cïÁž ¸“Zë/þ»sýÿÿãû€cðñýÿÿ_ÎvÿÿxqÈÓ³aêÃSù'¿¬ÄE„)0ƒ—b tÅ{xr€<‡Ó€BV¬Íæ÷—¨ÿ±@ÊèÎ[Æû¿ýC8@š@ñÀ:›õ7PÓDd 3ýzÍsïÿMoáš@‘Ê;ÿå/Á4H±}Ì£ÿwþ×¼ðþßü6èÛ‡ÐÿÓO¬úÿûùŽÿ×V­ø¿ëü&P2g °.—5~ÿÓ®˜5Õ¾ðùÏ9íÿõ‹À8Û¼óÿ½‹oÿ?¾÷ÿ¿_ò<Z€k¸ç×ÿìý…ÿS.›þ Ýp3æYLÒoÙƒ“-¨è€%]d‹ÞƒÛ²ãÿ{¬ ùµl+ó¢[@ȆO’[-ø?ÿ.°0}èò”7@åSÓ[T‹²ï¹üg›Íúÿâº5ÿ¯Loü{fñÿ«¶ýŸ~d-0£1‚,zr(Ì\€‚@Éã «þ§]5—c lª2@Yd(Oœ1ú¯¹L÷ÿµ‹ÿþ?˜öÿ0a?^œúÿæ¦Màb ”¸—ï9 6Æç°b €“\Ò½»ßÿgìÏû/µœ÷ÊS‹ŒvÈýÏØ]ôÿÆåÿÿoÓóí þßX>ãÿÃyaÿo̬—‘ ÌpâÈ;P²µ‡™ @(ܹùëÿ“@…ÀR7ï@ÉÑ%\ÿ/™üZ¸âÂÎÿ·%3¨¹öņøÿ®þÿw&ûÿýEàÌ*ÉÏžú²Àf.@![àÞÑtéÿ`¶¼4à>л€ù;nEåÿÓ@A†Â‚Tz¼^ä÷ÿϾÈÿgþ¿¿¤þÿý;?þ÷u^þ 4g:‹ÀÌ Œd”Œh®½øT€‚âÐÎïÿß½ùÿÿÐ2ï@u È¥×Oü?½~ȵó£è…a€Â™~š<ê*Îýܺæóÿ÷@ ®]þú¿©úÈÀ¥@¬NlN ‚ €†™±.9Å2~3˜3ÂOIEND®B`‚nurpawiki-1.2.3/files/edit.png0000644000175000017500000000045610667075457017053 0ustar jhellstenjhellsten‰PNG  IHDRk½“Ê pHYs  šœtIMEÖ 3ˆ´ÍIDATxÚí“= Ä …_‚¹‚W°L‘Ê$unà<ÄÜÄÖ+¤ÎyAp Áuݸ,¦Ùb"Î÷Æ¿éB¸!–"cÌ— ¥¸Ï&)…“”D4I™ !â\xõ¸§?ðÞ·óçy2Æyï=ç¼}ÿÍ•ãþ»Ômýó<¼RjÛ¶u]Çq,€}ßc`­UJ]÷ï²,1@nQÀ1í‚ÿ`QƒKþÝ"¯Á®äœËsœs¡"Ô´ÖÖZ‡ºªŸožç"ÈuÇ0 /ïߦ{¯öãò ¬IEND®B`‚nurpawiki-1.2.3/about.ml0000644000175000017500000000271411133415525015740 0ustar jhellstenjhellsten(* Copyright (c) 2006-2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) open XHTML.M open Eliom_sessions open Eliom_parameters open Eliom_services open Eliom_predefmod.Xhtml open Lwt open Services open Types let about_page_html = [h1 [pcdata "About Nurpawiki"]; p [pcdata ("Nurpawiki v"^Version.version^ " Copyright (c) 2007, 2008 Janne Hellsten "); br (); br (); pcdata "See the "; XHTML.M.a ~a:[a_href (uri_of_string "http://code.google.com/p/nurpawiki")] [pcdata "project homepage"]; pcdata "."]] let _ = register about_page (fun sp () () -> Session.with_guest_login sp (fun cur_user sp -> return (Html_util.html_stub sp (Html_util.navbar_html sp ~cur_user about_page_html)))) nurpawiki-1.2.3/util.ml0000644000175000017500000000427011072131045015574 0ustar jhellstenjhellsten(* Copyright (c) 2007-2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) open CalendarLib let match_pcre_option ?(charpos=0) rex s = (* Pcre's ~pos seems to work quite differently from Str's begin character. The below sub string hack is to make Pcre extract behave the same way as Str's match *) let s = String.sub s charpos ((String.length s) - charpos) in try Some (Pcre.extract (* ~pos:charpos *) ~rex s) with Not_found -> None let iso_date_re = Pcre.regexp "([0-9]+)-([0-9]+)-([0-9]+)" let date_of_string s = match match_pcre_option iso_date_re s with Some r -> let year = int_of_string r.(1) in let month = int_of_string r.(2) in let day = int_of_string r.(3) in Date.make year month day | None -> assert false let iso_date_time_re = Pcre.regexp "([0-9]+)-([0-9]+)-([0-9]+) .*" let date_of_date_time_string s = match (match_pcre_option iso_date_time_re s, match_pcre_option iso_date_re s) with (Some r,_)|(_,Some r) -> let year = int_of_string r.(1) in let month = int_of_string r.(2) in let day = int_of_string r.(3) in Date.make year month day | _ -> Ocsigen_messages.errlog ("invalid date '"^s^"'"); assert false (** [del_substring s c] return [s] with all occurrences of substring [c] removed. *) let del_substring s c = let q = Pcre.regexp (Pcre.quote c) in Pcre.replace ~rex:q ~templ:"" s (* Unit tests *) let _ = let a = "\\*foo\\*baz\\*" in assert (del_substring a "\\*" = "foobaz"); let b = "__foo__" in assert (del_substring b "_" = "foo") nurpawiki-1.2.3/database.ml0000644000175000017500000005242211133415541016371 0ustar jhellstenjhellsten(* Copyright (c) 2006-2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) open Types module Psql = Postgresql module P = Printf open XHTML.M open Eliom_sessions open Config type connection = Psql.connection let (>>) f g = g f module ConnectionPool = struct open Psql (* We have only one connection to pool from for now. This will likely be extended for more connetcions in the future. There's no need for it yet though. *) let connection_mutex = Mutex.create () let connection : Postgresql.connection option ref = ref None let with_mutex m f = Mutex.lock m; try let r = f () in Mutex.unlock m; r with x -> Mutex.unlock m; raise x (* NOTE we may get a deadlock here if someone uses nested with_conn calls. This should not happen unless there's a programming error somewhere. This case should go away if there are more than one DB connections available for with_conn. Currently there's only one connection though. *) let with_conn_priv (f : (Psql.connection -> 'a)) = (* TODO the error handling here is not still very robust. *) with_mutex connection_mutex (fun () -> match !connection with Some c -> (* Re-use the old connection. *) (match c#status with Ok -> f c | Bad -> Ocsigen_messages.errlog "Database connection bad. Trying reset"; c#reset; match c#status with Ok -> f c | Bad -> Ocsigen_messages.errlog "Database connection still bad. Bail out"; raise (Error (Psql.Connection_failure "bad connection"))) | None -> let host = Option.default "localhost" dbcfg.db_host in let port = Option.default "" dbcfg.db_port in let password = Option.default "" dbcfg.db_pass in let c = new Psql.connection ~host ~port ~password ~dbname:dbcfg.db_name ~user:dbcfg.db_user () in connection := Some c; (* Search tables from nurpawiki schema first: *) f c) let with_conn f = try with_conn_priv f with (Psql.Error e) as ex -> Ocsigen_messages.errlog (P.sprintf "psql failed : %s\n" (Psql.string_of_error e)); raise ex | x -> raise x end let with_conn f = Lwt_preemptive.detach ConnectionPool.with_conn f (* Escape a string for SQL query *) let escape s = let b = Buffer.create (String.length s) in String.iter (function '\\' -> Buffer.add_string b "\\\\" | '\'' -> Buffer.add_string b "''" | '"' -> Buffer.add_string b "\"" | c -> Buffer.add_char b c) s; Buffer.contents b let todos_user_login_join = "FROM nw.todos LEFT OUTER JOIN nw.users ON nw.todos.user_id = nw.users.id" (* Use this tuple format when querying TODOs to be parsed by parse_todo_result *) let todo_tuple_format = "nw.todos.id,descr,completed,priority,activation_date,user_id,nw.users.login" let todo_of_row row = let id = int_of_string (List.nth row 0) in let descr = List.nth row 1 in let completed = (List.nth row 2) = "t" in let owner_id = List.nth row 5 in let owner = if owner_id = "" then None else Some { owner_id = int_of_string owner_id; owner_login = List.nth row 6; } in let pri = List.nth row 3 in { t_id = id; t_descr = descr; t_completed = completed; t_priority = int_of_string pri; t_activation_date = List.nth row 4; t_owner = owner; } let parse_todo_result res = List.fold_left (fun acc row -> let id = int_of_string (List.nth row 0) in IMap.add id (todo_of_row row) acc) IMap.empty res#get_all_lst let guarded_exec ~(conn : Psql.connection) query = try conn#exec query with (Psql.Error e) as ex -> (match e with Psql.Connection_failure msg -> P.eprintf "psql failed : %s\n" msg; raise ex | _ -> P.eprintf "psql failed : %s\n" (Psql.string_of_error e); raise ex) let insert_todo_activity ~user_id todo_id ?(page_ids=None) activity = let user_id_s = string_of_int user_id in match page_ids with None -> "INSERT INTO nw.activity_log(activity_id,user_id,todo_id) VALUES ("^ (string_of_int (int_of_activity_type activity))^", "^user_id_s^ ", "^todo_id^")" | Some pages -> let insert_pages = List.map (fun page_id -> "INSERT INTO nw.activity_in_pages(activity_log_id,page_id) "^ "VALUES (CURRVAL('nw.activity_log_id_seq'), "^string_of_int page_id^")") pages in let page_act_insert = String.concat "; " insert_pages in "INSERT INTO nw.activity_log(activity_id,user_id,todo_id) VALUES ("^ (string_of_int (int_of_activity_type activity))^", "^ user_id_s^", "^todo_id^"); "^ page_act_insert let insert_save_page_activity ~conn ~user_id (page_id : int) = let sql = "BEGIN; INSERT INTO nw.activity_log(activity_id, user_id) VALUES ("^(string_of_int (int_of_activity_type AT_edit_page))^ " ,"^(string_of_int user_id)^"); INSERT INTO nw.activity_in_pages(activity_log_id,page_id) VALUES (CURRVAL('nw.activity_log_id_seq'), "^string_of_int page_id^"); COMMIT" in ignore (guarded_exec ~conn sql) let query_todos_by_ids ~conn todo_ids = if todo_ids <> [] then let ids = String.concat "," (List.map string_of_int todo_ids) in let r = guarded_exec ~conn ("SELECT "^todo_tuple_format^" "^todos_user_login_join^" WHERE nw.todos.id IN ("^ids^")") in List.map todo_of_row (r#get_all_lst) else [] let query_todo ~conn id = match query_todos_by_ids ~conn [id] with [task] -> Some task | [] -> None | _ -> None let todo_exists ~conn id = match query_todo ~conn id with Some _ -> true | None -> false let update_todo_activation_date ~conn todo_id new_date = let sql = "UPDATE nw.todos SET activation_date = '"^new_date^"' WHERE id = "^ (string_of_int todo_id) in ignore (guarded_exec ~conn sql) let update_todo_descr ~conn todo_id new_descr = let sql = "UPDATE nw.todos SET descr = '"^escape new_descr^"' WHERE id = "^ (string_of_int todo_id) in ignore (guarded_exec ~conn sql) let update_todo_owner_id ~conn todo_id owner_id = let owner_id_s = match owner_id with Some id -> string_of_int id | None -> "NULL" in let sql = "UPDATE nw.todos SET user_id = "^owner_id_s^" WHERE id = "^ (string_of_int todo_id) in ignore (guarded_exec ~conn sql) let select_current_user id = (match id with None -> "" | Some user_id -> " AND (user_id = "^string_of_int user_id^" OR user_id IS NULL) ") (* Query TODOs and sort by priority & completeness *) let query_all_active_todos ~conn ~current_user_id () = let r = guarded_exec ~conn ("SELECT "^todo_tuple_format^" "^todos_user_login_join^" "^ "WHERE activation_date <= current_date AND completed = 'f' "^ select_current_user current_user_id^ "ORDER BY completed,priority,id") in List.map todo_of_row r#get_all_lst let query_upcoming_todos ~conn ~current_user_id date_criterion = let date_comparison = let dayify d = "'"^string_of_int d^" days'" in match date_criterion with (None,Some days) -> "(activation_date > now()) AND (now()+interval "^dayify days^ " >= activation_date)" | (Some d1,Some d2) -> let sd1 = dayify d1 in let sd2 = dayify d2 in "(activation_date > now()+interval "^sd1^") AND (now()+interval "^sd2^ " >= activation_date)" | (Some d1,None) -> let sd1 = dayify d1 in "(activation_date > now()+interval "^sd1^")" | (None,None) -> "activation_date <= now()" in let r = guarded_exec ~conn ("SELECT "^todo_tuple_format^" "^todos_user_login_join^" "^ "WHERE "^date_comparison^ select_current_user current_user_id^ " AND completed='f' ORDER BY activation_date,priority,id") in List.map todo_of_row r#get_all_lst let new_todo ~conn page_id user_id descr = (* TODO: could wrap this into BEGIN .. COMMIT if I knew how to return the data from the query! *) let sql = "INSERT INTO nw.todos(user_id,descr) values('"^(string_of_int user_id)^"','"^escape descr^"'); INSERT INTO nw.todos_in_pages(todo_id,page_id) values(CURRVAL('nw.todos_id_seq'), " ^string_of_int page_id^");"^ (insert_todo_activity ~user_id "(SELECT CURRVAL('nw.todos_id_seq'))" ~page_ids:(Some [page_id]) AT_create_todo)^"; SELECT CURRVAL('nw.todos_id_seq')" in let r = guarded_exec ~conn sql in (* Get ID of the inserted item: *) (r#get_tuple 0).(0) (* Mapping from a todo_id to page list *) let todos_in_pages ~conn todo_ids = (* Don't query if the list is empty: *) if todo_ids = [] then IMap.empty else let ids = String.concat "," (List.map string_of_int todo_ids) in let sql = "SELECT todo_id,page_id,page_descr "^ "FROM nw.todos_in_pages,nw.pages WHERE todo_id IN ("^ids^") AND page_id = nw.pages.id" in let r = guarded_exec ~conn sql in let rows = r#get_all_lst in List.fold_left (fun acc row -> let todo_id = int_of_string (List.nth row 0) in let page_id = int_of_string (List.nth row 1) in let page_descr = List.nth row 2 in let lst = try IMap.find todo_id acc with Not_found -> [] in IMap.add todo_id ({ p_id = page_id; p_descr = page_descr }::lst) acc) IMap.empty rows (* TODO must not query ALL activities. Later we only want to currently visible activities => pages available. *) let query_activity_in_pages ~conn ~min_id ~max_id = let sql = "SELECT activity_log_id,page_id,page_descr FROM nw.activity_in_pages,nw.pages WHERE page_id = pages.id AND (activity_log_id > "^string_of_int min_id^" AND activity_log_id <= "^string_of_int max_id^")" in let r = guarded_exec ~conn sql in List.fold_left (fun acc row -> let act_id = int_of_string (List.nth row 0) in let page_id = int_of_string (List.nth row 1) in let page_descr = List.nth row 2 in let lst = try IMap.find act_id acc with Not_found -> [] in IMap.add act_id ({ p_id = page_id; p_descr = page_descr }::lst) acc) IMap.empty (r#get_all_lst) (* Note: This function should only be used in contexts where there will be no concurrency issues. Automated sessions should be used for real ID inserts. In its current form, this function is used to get the highest activity log item ID in order to display history separated into multiple web pages. *) let query_highest_activity_id ~conn = let sql = "SELECT last_value FROM nw.activity_log_id_seq" in let r = guarded_exec ~conn sql in int_of_string (r#get_tuple 0).(0) (* Collect todos in the current page *) let query_page_todos ~conn page_id = let sql = "SELECT "^todo_tuple_format^" "^todos_user_login_join^" WHERE nw.todos.id in "^ "(SELECT todo_id FROM nw.todos_in_pages WHERE page_id = "^string_of_int page_id^")" in let r = guarded_exec ~conn sql in parse_todo_result r (* Make sure todos are assigned to correct pages and that pages don't contain old todos moved to other pages or removed. *) let update_page_todos ~conn page_id todos = let page_id' = string_of_int page_id in let sql = "BEGIN; DELETE FROM nw.todos_in_pages WHERE page_id = "^page_id'^";"^ (String.concat "" (List.map (fun todo_id -> "INSERT INTO nw.todos_in_pages(todo_id,page_id)"^ " values("^(string_of_int todo_id)^", "^page_id'^");") todos)) ^ "COMMIT" in ignore (guarded_exec ~conn sql) (* Mark task as complete and set completion date for today *) let complete_task_generic ~conn ~user_id id op = let (activity,task_complete_flag) = match op with `Complete_task -> (AT_complete_todo, "t") | `Resurrect_task -> (AT_uncomplete_todo, "f") in let page_ids = try Some (List.map (fun p -> p.p_id) (IMap.find id (todos_in_pages ~conn [id]))) with Not_found -> None in let ids = string_of_int id in let sql = "BEGIN; UPDATE nw.todos SET completed = '"^task_complete_flag^"' where id="^ids^";"^ (insert_todo_activity ~user_id ids ~page_ids activity)^"; COMMIT" in ignore (guarded_exec ~conn sql) (* Mark task as complete and set completion date for today *) let complete_task ~conn ~user_id id = complete_task_generic ~conn ~user_id id `Complete_task let uncomplete_task ~conn ~user_id id = complete_task_generic ~conn ~user_id id `Resurrect_task let query_task_priority ~conn id = let sql = "SELECT priority FROM nw.todos WHERE id = "^string_of_int id in let r = guarded_exec ~conn sql in int_of_string (r#get_tuple 0).(0) (* TODO offset_task_priority can probably be written in one query instead of two (i.e., first one SELECT and then UPDATE based on that. *) let offset_task_priority ~conn id incr = let pri = min (max (query_task_priority ~conn id + incr) 1) 3 in let sql = "UPDATE nw.todos SET priority = '"^(string_of_int pri)^ "' where id="^string_of_int id in ignore (guarded_exec ~conn sql) let up_task_priority id = offset_task_priority id (-1) let down_task_priority id = offset_task_priority id 1 let new_wiki_page ~conn ~user_id page = let sql = "INSERT INTO nw.pages (page_descr) VALUES ('"^escape page^"'); INSERT INTO nw.wikitext (page_id,page_created_by_user_id,page_text) VALUES ((SELECT CURRVAL('nw.pages_id_seq')), "^string_of_int user_id^", ''); "^ "SELECT CURRVAL('nw.pages_id_seq')" in let r = guarded_exec ~conn sql in int_of_string ((r#get_tuple 0).(0)) (* See WikiPageVersioning on docs wiki for more details on the SQL queries. *) let save_wiki_page ~conn page_id ~user_id lines = let page_id_s = string_of_int page_id in let user_id_s = string_of_int user_id in let escaped = escape (String.concat "\n" lines) in (* Ensure no one else can update the head revision while we're modifying it Selecting for UPDATE means no one else can SELECT FOR UPDATE this row. If value (head_revision+1) is only computed and used inside this row lock, we should be protected against two (or more) users creating the same revision head. *) let sql = " BEGIN; SELECT * from nw.pages WHERE id = "^page_id_s^"; -- Set ID of next revision UPDATE nw.pages SET head_revision = nw.pages.head_revision+1 WHERE id = "^page_id_s^"; -- Kill search vectors for previous version so that only -- the latest version of the wikitext can be found using -- full text search. -- -- NOTE tsearch2 indexing trigger is set to run index updates -- only on INSERTs and not on UPDATEs. I wanted to be -- more future proof and set it trigger on UPDATE as well, -- but I don't know how to NOT have tsearch2 trigger -- overwrite the below UPDATE with its own index. UPDATE nw.wikitext SET page_searchv = NULL WHERE page_id = "^page_id_s^"; INSERT INTO nw.wikitext (page_id, page_created_by_user_id, page_revision, page_text) VALUES ("^page_id_s^", "^user_id_s^", (SELECT head_revision FROM nw.pages where id = "^page_id_s^"), E'"^escaped^"'); COMMIT" in ignore (guarded_exec ~conn sql) let find_page_id ~conn descr = let sql = "SELECT id FROM nw.pages WHERE page_descr = '"^escape descr^"' LIMIT 1" in let r = guarded_exec ~conn sql in if r#ntuples = 0 then None else Some (int_of_string (r#get_tuple 0).(0)) let page_id_of_page_name ~conn descr = Option.get (find_page_id ~conn descr) let wiki_page_exists ~conn page_descr = find_page_id ~conn page_descr <> None let is_legal_page_revision ~conn page_id_s rev_id = let sql = " SELECT page_id FROM nw.wikitext WHERE page_id="^page_id_s^" AND page_revision="^string_of_int rev_id in let r = guarded_exec ~conn sql in r#ntuples <> 0 (* Load a certain revision of a wiki page. If the given revision is not known, default to head revision. *) let load_wiki_page ~conn ?(revision_id=None) page_id = let page_id_s = string_of_int page_id in let head_rev_select = "(SELECT head_revision FROM nw.pages WHERE id = "^page_id_s^")" in let revision_s = match revision_id with None -> head_rev_select | Some r -> if is_legal_page_revision ~conn page_id_s r then string_of_int r else head_rev_select in let sql = " SELECT page_text FROM nw.wikitext WHERE page_id="^string_of_int page_id^" AND page_revision="^revision_s^" LIMIT 1" in let r = guarded_exec ~conn sql in (r#get_tuple 0).(0) let query_page_revisions ~conn page_descr = match find_page_id ~conn page_descr with None -> [] | Some page_id -> let option_of_empty s f = if s = "" then None else Some (f s) in let sql = " SELECT page_revision,nw.users.id,nw.users.login,date_trunc('second', page_created) FROM nw.wikitext LEFT OUTER JOIN nw.users on page_created_by_user_id = nw.users.id WHERE page_id = "^string_of_int page_id^" ORDER BY page_revision DESC" in let r = guarded_exec ~conn sql in List.map (fun r -> { pr_revision = int_of_string (List.nth r 0); pr_owner_id = option_of_empty (List.nth r 1) int_of_string; pr_owner_login = option_of_empty (List.nth r 2) Std.identity; pr_created = List.nth r 3; }) (r#get_all_lst) let query_past_activity ~conn ~min_id ~max_id = let sql = "SELECT nw.activity_log.id,activity_id,activity_timestamp,nw.todos.descr,nw.users.login FROM nw.activity_log LEFT OUTER JOIN nw.todos ON nw.activity_log.todo_id = nw.todos.id LEFT OUTER JOIN nw.users ON nw.activity_log.user_id = nw.users.id WHERE nw.activity_log.activity_timestamp < now() AND (nw.activity_log.id > "^string_of_int min_id^" AND nw.activity_log.id <= "^string_of_int max_id^") ORDER BY activity_timestamp DESC" in let r = guarded_exec ~conn sql in r#get_all_lst >> List.map (fun row -> let id = int_of_string (List.nth row 0) in let act_id = List.nth row 1 in let time = List.nth row 2 in let descr = List.nth row 3 in let user = List.nth row 4 in { a_id = id; a_activity = activity_type_of_int (int_of_string act_id); a_date = time; a_todo_descr = if descr = "" then None else Some descr; a_changed_by = if user = "" then None else Some user }) (* Search features *) let search_wikipage ~conn str = let escaped_ss = escape str in let sql = "SELECT page_id,headline,page_descr FROM nw.findwikipage('"^escaped_ss^"') "^ "LEFT OUTER JOIN nw.pages on page_id = nw.pages.id ORDER BY rank DESC" in let r = guarded_exec ~conn sql in r#get_all_lst >> List.map (fun row -> let id = int_of_string (List.nth row 0) in let hl = List.nth row 1 in { sr_id = id; sr_headline = hl; sr_page_descr = Some (List.nth row 2); sr_result_type = SR_page }) let user_query_string = "SELECT id,login,passwd,real_name,email FROM nw.users" let user_of_sql_row row = let id = int_of_string (List.nth row 0) in { user_id = id; user_login = (List.nth row 1); user_passwd = (List.nth row 2); user_real_name = (List.nth row 3); user_email = (List.nth row 4); } let query_users ~conn = let sql = user_query_string ^ " ORDER BY id" in let r = guarded_exec ~conn sql in r#get_all_lst >> List.map user_of_sql_row let query_user ~conn username = let sql = user_query_string ^" WHERE login = '"^escape username^"' LIMIT 1" in let r = guarded_exec ~conn sql in if r#ntuples = 0 then None else Some (user_of_sql_row (r#get_tuple_lst 0)) let add_user ~conn ~login ~passwd ~real_name ~email = let sql = "INSERT INTO nw.users (login,passwd,real_name,email) "^ "VALUES ("^(String.concat "," (List.map (fun s -> "'"^escape s^"'") [login; passwd; real_name; email]))^")" in ignore (guarded_exec ~conn sql) let update_user ~conn~user_id ~passwd ~real_name ~email = let sql = "UPDATE nw.users SET "^ (match passwd with None -> "" | Some passwd -> "passwd = '"^escape passwd^"',")^ "real_name = '"^escape real_name^"', email = '"^escape email^"' WHERE id = "^(string_of_int user_id) in ignore (guarded_exec ~conn sql) (* Highest upgrade schema below must match this version *) let nurpawiki_schema_version = 3 nurpawiki-1.2.3/META.in0000644000175000017500000000017010733527776015365 0ustar jhellstenjhellstenrequires = "unix,extlib,postgresql,calendar,pcre,str" version = "%_NURPAWIKI_VERSION_%" archive(byte) = "nurpawiki.cma" nurpawiki-1.2.3/privileges.ml0000644000175000017500000000563611072131045016777 0ustar jhellstenjhellsten(* Copyright (c) 2006-2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) (* Logic to handle user privileges. Instead of cluttering HTML generation and other logic with privilege handling, abstract it behind a tight interface. This interface also allows for a later addition of a more fine-grained access control. *) open Types (** with_can_create_user [user f on_fail] calls [f ()] if user is privileged enough to perform the operation. Otherwise call [on_fail error] to handle the error case. *) let with_can_create_user cur_user f ~on_fail = if cur_user.user_login = "admin" then f () else on_fail ("User '"^cur_user.user_login^"' is not permitted to create new users") let can_view_users cur_user = cur_user.user_login = "admin" (** with_can_view_users [user f] calls [f ()] if user is privileged enough to view a list of all users. Otherwise return an error message. *) let with_can_view_users cur_user f ~on_fail = if can_view_users cur_user then f () else on_fail ("User '"^cur_user.user_login^"' is not permitted to view other users") (** with_can_edit_user [user cur_user user_to_edit f] calls [f ()] if user is privileged enough to perform the operation. Otherwise return an error message. *) let with_can_edit_user cur_user target f ~on_fail = if cur_user.user_login = "admin" || cur_user.user_login = target.user_login then f () else on_fail ("User '"^cur_user.user_login^"' is not permitted to edit users other than self") (** Privileged enough to schedule tasks for all users? *) let can_schedule_all_tasks cur_user = cur_user.user_login = "admin" let user_owns_task_or_is_admin todo cur_user = if cur_user.user_login = "admin" then true else match todo.t_owner with Some o -> o.owner_id = cur_user.user_id | None -> false let can_edit_task todo cur_user = user_owns_task_or_is_admin todo cur_user let can_complete_task ~conn task_id cur_user = let todo = Database.query_todo ~conn task_id in match todo with Some t -> user_owns_task_or_is_admin t cur_user | None -> false let can_modify_task_priority ~conn task_id cur_user = let todo = Database.query_todo ~conn task_id in match todo with Some t -> user_owns_task_or_is_admin t cur_user | None -> false nurpawiki-1.2.3/test/0000755000175000017500000000000011251252512015243 5ustar jhellstenjhellstennurpawiki-1.2.3/test/postgresql/0000755000175000017500000000000011251252511017445 5ustar jhellstenjhellstennurpawiki-1.2.3/test/postgresql/Makefile0000644000175000017500000000020511070106063021101 0ustar jhellstenjhellsten CAMLC = ocamlfind ocamlc -thread -g $(LIB) LIB = -package extlib,postgresql -linkpkg all: $(CAMLC) $(LIB) psqltest.ml -o psqltest nurpawiki-1.2.3/test/postgresql/psqltest.ml0000644000175000017500000000177411070106063021666 0ustar jhellstenjhellsten module Psql = Postgresql module P = Printf let guarded_exec ~(conn : Psql.connection) query = try conn#exec query with (Psql.Error e) as ex -> (match e with Psql.Connection_failure msg -> P.eprintf "psql failed : %s\n" msg; raise ex | _ -> P.eprintf "psql failed : %s\n" (Psql.string_of_error e); raise ex) let _ = Printf.printf "Postgresql <-> Nurpawiki DB installation test.\n"; let db_user = "postgres" in let db_name = "nurpawiki" in let db_passwd = "barfoo" in let conn = new Psql.connection ~host:"localhost" ~dbname:db_name ~user:db_user (* ~port:(Option.default "" dbcfg.db_port)*) ~password:db_passwd () in let sql = "SELECT schemaname,tablename from pg_tables WHERE (schemaname = 'public' OR schemaname = 'nw') AND tablename = 'todos'" in let r = guarded_exec ~conn sql in let row_str = String.concat "." (List.hd r#get_all_lst) in Printf.printf "DB result: '%s'\n" row_str nurpawiki-1.2.3/test/results.txt0000644000175000017500000000055510727037255017526 0ustar jhellstenjhellsten unit of measurement: page view/s Date WikiStart /history "bm empty" "bm db1" ---------------------------------------------------------- 2007-01-31 0.065 0.195 2007-03-06 0.051 0.217 0.017 0.019 2007-03-13 0.051 0.24 0.017 0.020 2007-04-14 0.075 0.31 0.026 0.27 nurpawiki-1.2.3/test/stress/0000755000175000017500000000000011251252511016565 5ustar jhellstenjhellstennurpawiki-1.2.3/test/stress/stress.sh0000644000175000017500000000021410736154703020454 0ustar jhellstenjhellsten#!/bin/sh mkdir tmp for i in `seq 0 10000`; do echo $i wget -r http://localhost:8080/view?p=WikiStart -o /dev/null -l1 -P tmp done nurpawiki-1.2.3/test/functional/0000755000175000017500000000000011251252511017404 5ustar jhellstenjhellstennurpawiki-1.2.3/test/functional/TestSuite.html0000644000175000017500000000126310740170303022225 0ustar jhellstenjhellsten
Nurpawiki test suite
First run after DB creation
Create test1 user and login with it
Change test1 user password and login with new user
test4_create_FooBar_wiki_page
Add a to-do
Complete the added to-do
nurpawiki-1.2.3/test/functional/test2.html0000644000175000017500000000352210740170303021335 0ustar jhellstenjhellsten test2
test2
open /about
clickAndWait link=Logout
clickAndWait link=Take me to Nurpawiki
clickAndWait link=here
type login admin
type passwd
clickAndWait //input[@value='Login']
clickAndWait link=Edit Users
type login test1
type pass test1
type pass2 test1
type name Test User
type email foo@foo.com
clickAndWait //input[@value='Add User']
verifyTextPresent Test User
clickAndWait link=Logout
clickAndWait link=Take me to Nurpawiki
clickAndWait link=here
type login test1
type passwd test1
clickAndWait //input[@value='Login']
clickAndWait link=My Preferences
verifyTextPresent Edit User
verifyTextPresent test1
nurpawiki-1.2.3/test/functional/test3_change_test1_passwd.html0000644000175000017500000000310110740170303025335 0ustar jhellstenjhellsten test3_change_test1_passwd
test3_change_test1_passwd
open /view?p=WikiStart
clickAndWait link=Logout
clickAndWait link=Take me to Nurpawiki
clickAndWait link=here
type login test1
type passwd test1
clickAndWait //input[@value='Login']
clickAndWait link=My Preferences
type pass test1x
type pass2 test1x
type name Test User
clickAndWait //input[@value='Save User']
clickAndWait link=Logout
clickAndWait link=Take me to Nurpawiki
clickAndWait link=here
type login test1
type passwd test1x
clickAndWait //input[@value='Login']
verifyTextPresent test1
nurpawiki-1.2.3/test/functional/test6_complete_todo.html0000644000175000017500000000164210740170303024257 0ustar jhellstenjhellsten test6_complete_todo
test6_complete_todo
open /view?p=WikiStart
clickAndWait link=Logout
clickAndWait link=Take me to Nurpawiki
clickAndWait link=here
type login admin
type passwd
clickAndWait //input[@value='Login']
clickAndWait //img[@alt='Mark complete']
verifyTextPresent Completed task
nurpawiki-1.2.3/test/functional/test4_create_FooBar_wiki_page.html0000644000175000017500000000271510740170303026134 0ustar jhellstenjhellsten test4_create_FooBar_wiki_page
test4_create_FooBar_wiki_page
open /view?p=WikiStart
clickAndWait link=Logout
clickAndWait link=Take me to Nurpawiki
clickAndWait link=here
type login admin
type passwd
clickAndWait //input[@value='Login']
clickAndWait link=Edit page
type value = Nurpawiki =

See WikiMarkup for help on getting started.

Wiki page FooBar
clickAndWait //input[@value='Save']
clickAndWait link=FooBar
clickAndWait link=Create new page
type value = New Page =

Foo bar page.
clickAndWait //input[@value='Save']
verifyTextPresent Foo bar page
nurpawiki-1.2.3/test/functional/test1.html0000644000175000017500000000115410740170303021333 0ustar jhellstenjhellsten test1
test1
open /upgrade
clickAndWait link=Take me to Nurpawiki
clickAndWait link=About
verifyTextPresent Nurpawiki
verifyTextPresent Copyright
nurpawiki-1.2.3/test/functional/README0000644000175000017500000000030610740170303020263 0ustar jhellstenjhellstenThis directory contains .html files that are to be used with Selenium Core (or IDE). See the Nurpawiki wiki docs (http://code.google.com/p/nurpawiki) for instructions on how to run the test suite. nurpawiki-1.2.3/test/functional/test5_add_a_todo.html0000644000175000017500000000220610740170303023473 0ustar jhellstenjhellsten test5_add_a_todo
test5_add_a_todo
open /disconnect
clickAndWait link=Take me to Nurpawiki
clickAndWait link=FooBar
clickAndWait link=Edit page
type login test1
type login admin
type passwd
clickAndWait //input[@value='Login']
type value = New Page =

Foo bar page.

* [todo Add todo 1]
clickAndWait //input[@value='Save']
clickAndWait link=Home
verifyTextPresent Add todo 1
nurpawiki-1.2.3/test/bench.sh0000755000175000017500000000144110727037255016675 0ustar jhellstenjhellsten#!/bin/sh N=100 BN=500 test_wiki_start() { i=0 while [ "$i" -lt $N ]; do curl "http://localhost:8080/view?p=WikiStart" > /dev/null 2> /dev/null i=`expr $i + 1` done } test_history() { i=0 while [ "$i" -lt $N ]; do curl "http://localhost:8080/history" > /dev/null 2> /dev/null i=`expr $i + 1` done } test_benchmark() { i=0 while [ "$i" -lt $BN ]; do curl "http://localhost:8080/benchmark?test=$1" > /dev/null 2> /dev/null i=`expr $i + 1` done } echo View WikiStart $N times time -p test_wiki_start echo echo "View /history $N times" time -p test_history echo echo "View /benchmark?test=empty $BN times" time -p test_benchmark empty echo echo "View /benchmark?test=db1 $BN times" time -p test_benchmark db1 nurpawiki-1.2.3/_tags0000644000175000017500000000010311133415460015300 0ustar jhellstenjhellsten<*.cmx>: for-pack(Nurpawiki) : -for-pack(Nurpawiki) nurpawiki-1.2.3/types.ml0000644000175000017500000000574311072131045015771 0ustar jhellstenjhellsten(* Copyright (c) 2006-2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) module OrdInt = struct type t = int let compare a b = compare a b end module IMap = Map.Make (OrdInt) (* Exceptions returned by Eliom actions *) exception Action_completed_task of int exception Action_task_priority_changed of int type user = { user_id : int; user_login : string; user_passwd : string; user_real_name : string; user_email : string; } type todo = { t_id : int; t_descr : string; t_completed : bool; t_priority : int; t_activation_date : string; t_owner : owner option; } and owner = { owner_id : int; owner_login : string; } type page = { p_id : int; p_descr : string; } type page_revision = { pr_revision : int; pr_created : string; pr_owner_id : int option; pr_owner_login : string option; } type activity_type = AT_create_todo | AT_complete_todo | AT_work_on_todo | AT_create_page | AT_edit_page | AT_uncomplete_todo type activity = { a_id : int; a_activity : activity_type; a_date : string; a_todo_descr : string option; a_changed_by : string option; } type search_result_type = SR_page | SR_todo type search_result = { sr_id : int; sr_headline : string; sr_result_type : search_result_type; sr_page_descr : string option; } type et_cont = ET_scheduler | ET_view of string let et_cont_view_re = Pcre.regexp "^v_(.*)$" let string_of_et_cont = function ET_scheduler -> "s" | ET_view src_page -> "v_"^src_page let match_pcre_option rex s = try Some (Pcre.extract ~rex s) with Not_found -> None let et_cont_of_string s = if s = "s" then ET_scheduler else begin match match_pcre_option et_cont_view_re s with None -> raise (Failure "et_cont_of_string") | Some s -> ET_view s.(1) end let int_of_activity_type = function AT_create_todo -> 1 | AT_complete_todo -> 2 | AT_work_on_todo -> 3 | AT_create_page -> 4 | AT_edit_page -> 5 | AT_uncomplete_todo -> 6 let activity_type_of_int = function 1 -> AT_create_todo | 2 -> AT_complete_todo | 3 -> AT_work_on_todo | 4 -> AT_create_page | 5 -> AT_edit_page | 6 -> AT_uncomplete_todo | _ -> assert false nurpawiki-1.2.3/VERSION0000644000175000017500000000000611251252152015330 0ustar jhellstenjhellsten1.2.3 nurpawiki-1.2.3/services.ml0000644000175000017500000000511011072131045016434 0ustar jhellstenjhellsten(* Copyright (c) 2006-2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) open XHTML.M open Eliom_sessions open Eliom_parameters open Eliom_services open Eliom_predefmod.Xhtml open Config open Types open Lwt let wiki_view_page = new_service ["view"] ((string "p") ** (opt (bool "printable")) ** (opt (int "r")) ** (opt (bool "force_login"))) () let wiki_start = Eliom_predefmod.String_redirection.register_new_service [] unit (fun sp _ _ -> return (make_full_uri wiki_view_page sp (Config.site.cfg_homepage, (None, (None, None))))) let wiki_edit_page = new_service ["edit"] (string "p") () let scheduler_page = new_service ["scheduler"] unit () let edit_todo_get_page = new_service ["edit_todo"] ((Eliom_parameters.user_type et_cont_of_string string_of_et_cont "src_service") ** (opt (int "tid"))) () let edit_todo_page = new_post_service ~fallback:edit_todo_get_page ~post_params:any () let history_page = new_service ["history"] (opt (int "nth_p")) () let search_page = new_service ["search"] (string "q") () let benchmark_page = new_service ["benchmark"] (string "test") () let user_admin_page = new_service ["user_admin"] unit () let edit_user_page = new_service ["edit_user"] (opt (string "caller") ** (string "user_to_edit")) () let disconnect_page = new_service ["disconnect"] unit () let about_page = new_service ["about"] unit () let page_revisions_page = new_service ["page_revisions"] (string "p") () let task_side_effect_complete_action = Eliom_services.new_coservice' ~get_params:(Eliom_parameters.int "task_id") () let task_side_effect_undo_complete_action = Eliom_services.new_coservice' ~get_params:(Eliom_parameters.int "task_id") () let task_side_effect_mod_priority_action = Eliom_services.new_coservice' ~get_params:((Eliom_parameters.int "task_id") ** Eliom_parameters.bool "dir") () nurpawiki-1.2.3/page_revisions.ml0000644000175000017500000000371411133415525017644 0ustar jhellstenjhellsten(* Copyright (c) 2006-2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) open XHTML.M open Eliom_sessions open Eliom_parameters open Eliom_services open Eliom_predefmod.Xhtml open Lwt open ExtList open ExtString open Services open Types module Db = Database let revision_table sp page_descr = Db.with_conn (fun conn -> Db.query_page_revisions ~conn page_descr) >>= fun revisions -> let page_link descr (rev:int) = a ~sp ~service:wiki_view_page [pcdata ("Revision "^(string_of_int rev))] (descr, (None, (Some rev, None))) in let rows = List.map (fun r -> tr (td [page_link page_descr r.pr_revision]) [td [pcdata r.pr_created]; td [pcdata (Option.default "" r.pr_owner_login)]]) revisions in return [table (tr (th [pcdata "Revision"]) [th [pcdata "When"]; th [pcdata "Changed by"]]) rows] let view_page_revisions sp page_descr = Session.with_guest_login sp (fun cur_user sp -> revision_table sp page_descr >>= fun revisions -> return (Html_util.html_stub sp (Html_util.navbar_html sp ~cur_user (h1 [pcdata (page_descr ^ " Revisions")] :: revisions)))) (* /page_revisions?page_id= *) let _ = register page_revisions_page (fun sp page_descr () -> view_page_revisions sp page_descr) nurpawiki-1.2.3/version.ml.in0000644000175000017500000000004710734544453016726 0ustar jhellstenjhellsten let version = "%_NURPAWIKI_VERSION_%" nurpawiki-1.2.3/session.ml0000644000175000017500000002376111133415525016316 0ustar jhellstenjhellsten(* Copyright (c) 2006-2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) open Lwt open XHTML.M open Eliom_services open Eliom_parameters open Eliom_sessions open Eliom_predefmod.Xhtml open Services open Types open Config module Db = Database module Dbu = Database_upgrade let seconds_in_day = 60.0 *. 60.0 *. 24.0 let login_table = Eliom_sessions.create_persistent_table "login_table" (* Set password & login into session. We set the cookie expiration into 24h from now so that the user can even close his browser window, re-open it and still retain his logged in status. *) let set_password_in_session sp login_info = set_service_session_timeout ~sp None; set_persistent_data_session_timeout ~sp None >>= fun () -> set_persistent_data_session_cookie_exp_date ~sp (Some 3153600000.0) >>= fun () -> set_persistent_session_data ~table:login_table ~sp login_info let upgrade_page = new_service ["upgrade"] unit () let schema_install_page = new_service ["schema_install"] unit () let connect_action = Eliom_services.new_post_coservice' ~post_params:((string "login") ** (string "passwd")) () let link_to_nurpawiki_main sp = a ~sp ~service:wiki_view_page [pcdata "Take me to Nurpawiki"] (Config.site.cfg_homepage,(None,(None,None))) (* Get logged in user as an option *) let get_login_user sp = Eliom_sessions.get_persistent_session_data login_table sp () >>= fun session_data -> match session_data with Eliom_sessions.Data user -> Lwt.return (Some user) | Eliom_sessions.No_data | Eliom_sessions.Data_session_expired -> Lwt.return None let db_upgrade_warning sp = [h1 [pcdata "Database Upgrade Warning!"]; p [pcdata "An error occured when Nurpawiki was trying to access database."; br (); strong [ pcdata "You might be seeing this for a couple of reasons:"; br ()]; br (); pcdata "1) You just installed Nurpawiki and this is the first time you're running Nurpawiki on your database!"; br (); pcdata "2) You have upgraded an existing Nurpawiki installation and this is the first time you're running it since upgrade."; br (); br (); pcdata "In order to continue, your DB needs to be upgraded. "; pcdata "If you have valuable data in your DB, please take a backup of it before proceeding!"; br (); br (); a ~service:upgrade_page ~sp [pcdata "Upgrade now!"] ()]] let db_installation_error sp = [div [h1 [pcdata "Database schema not installed"]; br (); p [pcdata "It appears you're using your Nurpawiki installation for the first time. "; br (); br (); pcdata "In order to complete Nurpawiki installation, your Nurpawiki database schema needs to be initialized."]; p [pcdata "Follow this link to complete installation:"; br (); br (); a ~service:schema_install_page ~sp [pcdata "Install schema!"] ()]]] let login_html sp ~err = let help_text = [br (); br (); strong [pcdata "Please read "]; XHTML.M.a ~a:[a_id "login_help_url"; a_href (uri_of_string "http://code.google.com/p/nurpawiki/wiki/Tutorial")] [pcdata "Nurpawiki tutorial"]; pcdata " if you're logging in for the first time."; br ()] in Html_util.html_stub sp [div ~a:[a_id "login_outer"] [div ~a:[a_id "login_align_middle"] [Eliom_predefmod.Xhtml.post_form connect_action sp (fun (loginname,passwd) -> [table ~a:[a_class ["login_box"]] (tr (td ~a:[a_class ["login_text"]] (pcdata "Welcome to Nurpawiki!"::help_text)) []) [tr (td [pcdata ""]) []; tr (td ~a:[a_class ["login_text_descr"]] [pcdata "Username:"]) []; tr (td [string_input ~input_type:`Text ~name:loginname ()]) []; tr (td ~a:[a_class ["login_text_descr"]] [pcdata "Password:"]) []; tr (td [string_input ~input_type:`Password ~name:passwd ()]) []; tr (td [string_input ~input_type:`Submit ~value:"Login" ()]) []]; p err]) ()]]] let with_db_installed sp f = (* Check if the DB is installed. If so, check that it doesn't need an upgrade. *) Db.with_conn (fun conn -> if not (Dbu.is_schema_installed ~conn) then Some (Html_util.html_stub sp (db_installation_error sp)) else if Dbu.db_schema_version ~conn < Db.nurpawiki_schema_version then Some (Html_util.html_stub sp (db_upgrade_warning sp)) else None) >>= function | Some x -> return x | None -> f () (** Wrap page service calls inside with_user_login to have them automatically check for user login and redirect to login screen if not logged in. *) let with_user_login ?(allow_read_only=false) sp f = let login () = get_login_user sp >>= function | Some (login,passwd) -> begin Db.with_conn (fun conn -> Db.query_user ~conn login) >>= function | Some user -> let passwd_md5 = Digest.to_hex (Digest.string passwd) in (* Autheticate user against his password *) if passwd_md5 <> user.user_passwd then return (login_html sp [Html_util.error ("Wrong password given for user '"^login^"'")]) else f user sp | None -> return (login_html sp [Html_util.error ("Unknown user '"^login^"'")]) end | None -> if allow_read_only && Config.site.cfg_allow_ro_guests then let guest_user = { user_id = 0; user_login = "guest"; user_passwd = ""; user_real_name = "Guest"; user_email = ""; } in f guest_user sp else return (login_html sp []) in with_db_installed sp login (* Either pretend to be logged in as 'guest' (if allowed by config options) or require a proper login. If logging in as 'guest', we setup a dummy user 'guest' that is not a real user. It won't have access to write to any tables. *) let with_guest_login sp f = with_user_login ~allow_read_only:true sp f (* Same as with_user_login except that we can't generate HTML for any errors here. Neither can we present the user with a login box. If there are any errors, just bail out without doing anything harmful. *) let action_with_user_login sp f = Db.with_conn (fun conn -> Dbu.db_schema_version conn) >>= fun db_version -> if db_version = Db.nurpawiki_schema_version then get_login_user sp >>= function | Some (login,passwd) -> begin Db.with_conn (fun conn -> Db.query_user ~conn login) >>= function | Some user -> let passwd_md5 = Digest.to_hex (Digest.string passwd) in (* Autheticate user against his password *) if passwd_md5 = user.user_passwd then f user else return [] | None -> return [] end | None -> return [] else return [] let update_session_password sp login new_password = ignore (Eliom_sessions.close_session ~sp () >>= fun () -> set_password_in_session sp (login,new_password)) (* Check session to see what happened during page servicing. If any actions were called, some of them might've set values into session that we want to use for rendering the current page. *) let any_complete_undos sp = List.fold_left (fun acc e -> match e with Action_completed_task tid -> Some tid | _ -> acc) None (Eliom_sessions.get_exn sp) (* Same as any_complete_undos except we check for changed task priorities. *) let any_task_priority_changes sp = List.fold_left (fun acc e -> match e with Action_task_priority_changed tid -> tid::acc | _ -> acc) [] (Eliom_sessions.get_exn sp) let connect_action_handler sp () login_nfo = Eliom_sessions.close_session ~sp () >>= fun () -> set_password_in_session sp login_nfo >>= fun () -> return [] let () = Eliom_predefmod.Actions.register ~service:connect_action connect_action_handler (* /schema_install initializes the database schema (if needed) *) let _ = register schema_install_page (fun sp () () -> Db.with_conn (fun conn -> Database_schema.install_schema ~conn) >>= fun _ -> return (Html_util.html_stub sp [h1 [pcdata "Database installation completed"]; p [br (); link_to_nurpawiki_main sp]])) (* /upgrade upgrades the database schema (if needed) *) let _ = register upgrade_page (fun sp () () -> Db.with_conn (fun conn -> Dbu.upgrade_schema ~conn) >>= fun msg -> return (Html_util.html_stub sp [h1 [pcdata "Upgrade DB schema"]; (pre [pcdata msg]); p [br (); link_to_nurpawiki_main sp]])) let _ = register disconnect_page (fun sp () () -> (Eliom_sessions.close_session ~sp () >>= fun () -> return (Html_util.html_stub sp [h1 [pcdata "Logged out!"]; p [br (); link_to_nurpawiki_main sp]]))) nurpawiki-1.2.3/database_upgrade.ml0000644000175000017500000002011511133415474020077 0ustar jhellstenjhellsten(* Copyright (c) 2007-2008 Janne Hellsten *) (* * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received * a copy of the GNU General Public License along with this program. * If not, see . *) module Psql = Postgresql open Database let insert_initial_wiki_pages = "-- Insert main page and WikiMarkup pages into the DB INSERT INTO nw.pages (page_descr) VALUES ('WikiStart'); INSERT INTO nw.wikitext (page_id,page_text) VALUES ((SELECT CURRVAL('nw.pages_id_seq')), ' = Nurpawiki = See WikiMarkup for help on getting started. '); INSERT INTO nw.pages (page_descr) VALUES ('WikiMarkup'); INSERT INTO nw.wikitext (page_id,page_text) VALUES ((SELECT CURRVAL('nw.pages_id_seq')), ' = Wiki Markup Page = == Section heading == === Sub-section heading === == Formatting == === Italic === _Italic text_. Single _italic_ word. _Two_ _italic_ words. === Bold === *Bold faced text*. *Bold* word. *Bold* _with_ italic in same sentence. === Preformatted === Use `
` or `8<`:
8<
Preformatted text
WikiLink
[http://localhost/foo]
8<

== Bullet list ==

Paragraph of text.

Second paragraph of text.

* Bullet list top-level
* Another bullet on top-level
** Sub bullet
* Top-level again

== Links ==

A [wiki:WikiStart link] to the WikiStart main page.

Another [http://www.google.com link], this time to [http://www.google.com].

This !WikiText that does not become a link.  Write these as `!WikiText` to make Nurpawiki not regard it as a !WikiLink.  I.e., prefix it with a bang (!).
');"

let logged_exec ~conn logmsg sql = 
  Buffer.add_string logmsg ("  "^sql^"\n");
  ignore (guarded_exec ~conn sql)

(* Migrate all tables to version 1 from schema v0: *)
let upgrade_schema_from_0 ~conn logmsg =
  Buffer.add_string logmsg "Upgrading schema to version 1\n";
  (* Create version table and set version to 1: *)
  let sql = 
    "CREATE TABLE version (schema_version integer NOT NULL);
     INSERT INTO version (schema_version) VALUES('1')" in
  logged_exec ~conn logmsg sql;

  let empty_passwd = (Digest.to_hex (Digest.string "")) in
  let sql = 
    "CREATE TABLE users (id SERIAL, 
                         login text NOT NULL,
                         passwd varchar(64) NOT NULL,
                         real_name text,
                         email varchar(64));
     INSERT INTO users (login,passwd) VALUES('admin', '"^empty_passwd^"')" in
  logged_exec ~conn logmsg sql;

  (* Todos are now owned by user_id=0 *)
  let sql =
    "ALTER TABLE todos ADD COLUMN user_id integer" in
  logged_exec ~conn logmsg sql;

  (* Add user_id field to activity log table *)
  let sql =
    "ALTER TABLE activity_log ADD COLUMN user_id integer" in
  logged_exec ~conn logmsg sql


let table_exists ~conn ~schema ~table =
  let sql = 
    "SELECT * from pg_tables WHERE schemaname = '"^schema^"' 
     AND tablename = '"^table^"'" in
  let r = guarded_exec ~conn sql in
  r#ntuples <> 0

let function_exists ~conn fn =
  let sql = 
    "SELECT proname from pg_proc WHERE proname = '"^fn^"'" in
  let r = guarded_exec ~conn sql in
  r#ntuples <> 0

let redefine_wikitext_search ~conn schema = 
  let version = 
    match function_exists ~conn "tsvector_update_trigger" with
      true -> `Built_in_tsearch2
    | false ->
        if function_exists ~conn "tsearch2" then
          `No_built_in_tsearch2
        else (* TODO no tsearch2 installed, ISSUE ERROR! *)
          assert false in
  let proc = 
    match version with
      `No_built_in_tsearch2 ->
        "tsearch2('page_searchv', 'page_text')"
    | `Built_in_tsearch2 ->
        "tsvector_update_trigger(page_searchv, 'pg_catalog.english', page_text)" in
  "
-- Redefine wikitext tsearch2 update trigger to not trigger
-- on UPDATEs
DROP TRIGGER IF EXISTS wikitext_searchv_update ON "^schema^".wikitext;

CREATE TRIGGER wikitext_searchv_update
    BEFORE INSERT ON "^schema^".wikitext
    FOR EACH ROW
    EXECUTE PROCEDURE "^proc

let upgrade_schema_from_1 ~conn logmsg =
  Buffer.add_string logmsg "Upgrading schema to version 2\n";
  let sql = 
    "ALTER TABLE pages ADD COLUMN head_revision bigint not null default 0" in
  logged_exec ~conn logmsg sql;

  let sql = 
    "ALTER TABLE wikitext ADD COLUMN page_revision bigint not null default 0" in
  logged_exec ~conn logmsg sql;

  let sql =
    "ALTER TABLE wikitext
     ADD COLUMN page_created timestamp not null default now()" in  
  logged_exec ~conn logmsg sql;

  let sql = "ALTER TABLE wikitext ADD COLUMN page_created_by_user_id bigint" in
  logged_exec ~conn logmsg sql;

  (* Change various tsearch2 default behaviour: *)
  if table_exists ~conn ~schema:"public" ~table:"pg_ts_cfg" then
    let sql = "UPDATE pg_ts_cfg SET locale = current_setting('lc_collate') 
 WHERE ts_name = 'default'" in
    logged_exec ~conn logmsg sql
  else 
    ();
  let sql = redefine_wikitext_search ~conn "public" in
  logged_exec ~conn logmsg sql;

  logged_exec ~conn logmsg "UPDATE version SET schema_version = 2"

let findwikipage_function_sql prfx =
  "CREATE FUNCTION nw.findwikipage(text) RETURNS SETOF nw.findwikipage_t
    AS $_$
SELECT page_id, "^prfx^"headline(page_text, q), "^prfx^"rank(page_searchv, q) FROM nw.wikitext, to_tsquery($1) AS q WHERE page_searchv @@ q ORDER BY "^prfx^"rank(page_searchv, q) DESC$_$
    LANGUAGE sql"

(* Version 2 -> 3: move all tables under 'nw' schema *)
let upgrade_schema_from_2 ~conn logmsg =
  let tables = 
    ["users"; "todos"; "activity_in_pages"; "activity_log"; 
     "pages"; "version"; "wikitext"; "todos_in_pages"] in
  logged_exec ~conn logmsg "CREATE SCHEMA nw";
  List.iter
    (fun tbl ->
       let sql = "ALTER TABLE "^tbl^" SET SCHEMA nw" in
       logged_exec ~conn logmsg sql) tables;

  logged_exec ~conn logmsg (redefine_wikitext_search ~conn "nw");

  logged_exec ~conn logmsg "ALTER TYPE findwikipage_t SET SCHEMA nw";
  logged_exec ~conn logmsg "DROP FUNCTION findwikipage(text)";

  let create_find_fn_sql = 
    if function_exists ~conn "ts_rank" then
      findwikipage_function_sql "ts_" 
    else
      if function_exists ~conn "rank" then
        findwikipage_function_sql "" 
      else
        assert false in
  logged_exec ~conn logmsg create_find_fn_sql;

  logged_exec ~conn logmsg insert_initial_wiki_pages;

  (* TODO seqs, findwikipage *)
  logged_exec ~conn logmsg "UPDATE nw.version SET schema_version = 3"

(* TODO clean up *)
let db_schema_version ~conn =
  if table_exists ~conn ~schema:"nw" ~table:"version" then
    let r = guarded_exec ~conn "SELECT (nw.version.schema_version) FROM nw.version" in
    int_of_string (r#get_tuple 0).(0)
  else
    if not (table_exists ~conn ~schema:"public" ~table:"version") then
      0
    else 
      let r = guarded_exec ~conn "SELECT (version.schema_version) FROM version" in
      int_of_string (r#get_tuple 0).(0)

let upgrade_schema ~conn =
  (* First find out schema version.. *)
  let logmsg = Buffer.create 0 in
  if db_schema_version ~conn = 0 then
    begin
      Buffer.add_string logmsg "Schema is at version 0\n";
      upgrade_schema_from_0 ~conn logmsg
    end;
  if db_schema_version ~conn = 1 then
    begin
      Buffer.add_string logmsg "Schema is at version 1\n";
      upgrade_schema_from_1 ~conn logmsg
    end;
  if db_schema_version ~conn = 2 then
    begin
      Buffer.add_string logmsg "Schema is at version 2\n";
      upgrade_schema_from_2 ~conn logmsg
    end;
  assert (db_schema_version ~conn == nurpawiki_schema_version);
  Buffer.contents logmsg

(** Check whether the nurpawiki schema is properly installed on Psql *)
let is_schema_installed ~(conn : connection) =
  let sql = 
    "SELECT * from pg_tables WHERE (schemaname = 'public' OR schemaname = 'nw') AND "^
      "tablename = 'todos'" in
  let r = guarded_exec ~conn sql in
  r#ntuples <> 0
nurpawiki-1.2.3/nurpawiki.mlpack0000644000175000017500000000024211133415460017466 0ustar  jhellstenjhellstenVersion
Config
Types
Util
Database
Database_upgrade
Database_schema
Services
Privileges
Html_util
Session
User_editor
Page_revisions
Main
Scheduler
History
About
nurpawiki-1.2.3/ocsigen.conf.in0000644000175000017500000000253011067723013017173 0ustar  jhellstenjhellsten
  
    8080 
    ./var/log 
    ./var/lib

    UTF-8 

    
    

    
    
    
    
    
    
    

    
    

    
    

    
      
        

          

          
          

        
        
      


    

    ./var/run/ocsigen_command

  
  

nurpawiki-1.2.3/user_editor.ml0000644000175000017500000002336411133415525017156 0ustar  jhellstenjhellsten(* Copyright (c) 2006-2008 Janne Hellsten  *)

(* 
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 2 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.  You should have received
 * a copy of the GNU General Public License along with this program.
 * If not, see . 
 *)

open Lwt
open XHTML.M
open Eliom_sessions
open Eliom_parameters
open Eliom_services
open Eliom_predefmod.Xhtml

open Services
open Types

module Db = Database

let query_user login = Db.with_conn (fun conn -> Db.query_user ~conn login)

let service_create_new_user = 
  new_post_service
    ~fallback:user_admin_page
    ~post_params:((string "login") ** 
                    (string "pass") ** 
                    (string "pass2") **  (* re-type *)
                    (string "name") **
                    (string "email"))
    ()

let service_save_user_edit =
  new_post_service
    ~fallback:edit_user_page
    ~post_params:((string "pass") ** 
                    (string "pass2") **  (* re-type *)
                    (string "name") **
                    (string "email"))
    ()


let rec view_user_admin_page sp ~err ~cur_user =
  Db.with_conn (fun conn -> Db.query_users ~conn) >>= fun users ->
  let users_table = 
    table 
      (tr 
         (th 
            [pcdata "Id"]) 
         [th [pcdata "Login"]; 
          th [pcdata "Real Name"];
          th [pcdata "E-mail"]])
      (List.map 
         (fun user ->
            tr 
              (td [pcdata (string_of_int user.user_id)])
              [td [pcdata user.user_login];
               td [pcdata user.user_real_name];
               td [pcdata user.user_email];
               td [a ~service:edit_user_page ~sp [pcdata "Edit"] 
                     (Some "user_admin", user.user_login)]])
         users) in

  return
    (Html_util.html_stub sp
       (Html_util.navbar_html sp ~cur_user
          ([h1 [pcdata "Edit users"];
            users_table] @
             err @
            [post_form ~service:service_create_new_user ~sp
               (fun (login,(passwd,(passwd2,(name,email)))) ->
                  [h2 [pcdata "Create a new user"];
                   (table
                      (tr
                         (td [pcdata "Login:"])
                         [td [string_input ~input_type:`Text ~name:login ()]])
                      [tr
                         (td [pcdata "Password:"])
                         [td [string_input ~input_type:`Password ~name:passwd ()]];

                       tr
                         (td [pcdata "Re-type password:"])
                         [td [string_input ~input_type:`Password ~name:passwd2 ()]];

                       tr
                         (td [pcdata "Name:"])
                         [td [string_input ~input_type:`Text ~name:name ()]];

                       tr
                         (td [pcdata "E-mail address:"])
                         [td [string_input ~input_type:`Text ~name:email ()]];

                       tr
                         (td [string_input ~input_type:`Submit ~value:"Add User" ()])
                         []])]) ()])))

(* Only allow certain types of login names to avoid surprises *)
let sanitize_login_name name =
  let rex = Pcre.regexp "^[a-zA-Z_][a-zA-Z0-9_]*$" in
  try Some (Pcre.extract ~rex name).(0) with Not_found -> None

let save_user ~update_user ~login ~passwd ~passwd2 ~real_name ~email =
  let sanitized_login = sanitize_login_name login in
  match sanitized_login with
    None -> 
      return [Html_util.error ("Only alphanumeric chars are allowed in login name!  Got '"^login^"'")]
  | Some login ->
      query_user login >>= fun old_user ->
      if not update_user && old_user <> None then
        return [Html_util.error ("User '"^login^"' already exists!")]
      else if login = "guest" then
        return [Html_util.error ("Cannot create '"^login^"' user.  The login name 'guest' is reserved for internal use!")]
      else if passwd <> passwd2 then
        return [Html_util.error "Re-typed password doesn't match your password!"]
      else 
        begin
          let passwd_md5 = Digest.to_hex (Digest.string passwd) in
          if update_user then
            begin
              match old_user with
                Some u ->
                  (* If no password was entered, set it to old value: *)
                  let new_passwd_md5 = 
                    if passwd = "" then None else Some passwd_md5 in
                  Db.with_conn
                    (fun conn ->
                       Db.update_user ~conn
                         ~user_id:u.user_id ~passwd:new_passwd_md5 ~real_name ~email)
                  >>= fun _ -> return []
              | None ->
                  assert false 
            end
          else
            Db.with_conn
              (fun conn ->
                 Db.add_user ~conn ~login ~passwd:passwd_md5 ~real_name ~email)
            >>= fun _ -> return []
        end

let _ =
  register service_create_new_user
    (fun sp () (login,(passwd,(passwd2,(real_name, email))))  ->
       Session.with_user_login sp
         (fun cur_user sp ->
            Privileges.with_can_create_user cur_user 
              (fun () ->
                 save_user ~update_user:false
                   ~login ~passwd ~passwd2 ~real_name ~email >>= fun err ->
                 view_user_admin_page sp ~err ~cur_user)
              ~on_fail:(fun e -> return (Html_util.error_page sp e))))


let save_user_prefs c_passwd c_passwd2 (c_name,old_name) (c_email,old_email) =
  (table
     (tr
        (td [pcdata "New Password:"])
        [td [string_input ~input_type:`Password ~name:c_passwd ()];
        ])
     [tr
        (td [pcdata "Re-type Password:"])
        [td [string_input ~input_type:`Password ~name:c_passwd2 ()]];

      tr 
        (td [pcdata "Name:"])
        [td [string_input ~input_type:`Text ~name:c_name 
               ~value:old_name ()]];

      tr 
        (td [pcdata "E-mail Address:"])
        [td [string_input ~input_type:`Text ~name:c_email 
               ~value:old_email ()]];

      tr
        (td [string_input ~input_type:`Submit ~value:"Save User" ()])
        []])

let _ =
  register user_admin_page
    (fun sp _ () -> 
       Session.with_user_login sp
         (fun cur_user sp ->
            Privileges.with_can_view_users cur_user
              (fun () ->
                 view_user_admin_page sp ~err:[] ~cur_user) 
              ~on_fail:(fun e -> return (Html_util.error_page sp e))))


let rec view_edit_user_page sp caller ~err ~cur_user user_to_edit =
  Html_util.html_stub sp
    (Html_util.navbar_html sp ~cur_user
       ([h1 [pcdata "Edit User"]] @
          err @
          [post_form ~service:service_save_user_edit ~sp
             (fun (passwd,(passwd2,(name,email))) ->
                [h2 [pcdata ("Edit User '"^user_to_edit.user_login^"'")];
                 save_user_prefs passwd passwd2 
                   (name,user_to_edit.user_real_name) 
                   (email,user_to_edit.user_email)]) 
             (caller, user_to_edit.user_login)]))


let _ =
  register service_save_user_edit
    (fun sp (caller,login) (passwd,(passwd2,(real_name, email)))  ->
       Session.with_user_login sp
         (fun cur_user sp ->
            query_user login
            >>= function
              | Some user_to_edit ->
                  Privileges.with_can_edit_user cur_user user_to_edit
                    (fun () ->
                         save_user 
                           ~update_user:true 
                           ~login:login
                           ~passwd ~passwd2 ~real_name ~email >>= fun err ->
                       (* Update password in the session if we're editing current
                          user: *)
                       if err = [] && passwd <> "" && cur_user.user_login = login then
                         Session.update_session_password sp login passwd;
                       Session.with_user_login sp
                         (fun cur_user sp ->
                            match caller with
                                Some "user_admin" ->
                                  view_user_admin_page sp ~err ~cur_user
                              | Some _ -> 
                                  return (Html_util.error_page sp ("Invalid caller service!"))
                              | None ->
                                  query_user login
                                  >>= function
                                    | Some user ->
                                        return (view_edit_user_page sp caller ~err ~cur_user user)
                                    | None ->
                                        return (Html_util.error_page sp ("Invalid user!"))))
                    ~on_fail:(fun e -> return (Html_util.error_page sp e))
              | None ->
                  return (Html_util.error_page sp ("Trying to edit unknown user '"^login^"'"))))


let _ =
  register edit_user_page
    (fun sp (caller,editing_login) () -> 
       Session.with_user_login sp
         (fun cur_user sp ->
            query_user editing_login
            >>= function
              | Some user_to_edit ->
                  Privileges.with_can_edit_user cur_user user_to_edit
                    (fun () ->
                       return (view_edit_user_page sp caller ~err:[] ~cur_user user_to_edit))
                    ~on_fail:(fun e -> return (Html_util.error_page sp e))
              | None ->
                  return (Html_util.error_page sp ("Unknown user '"^editing_login^"'"))))
nurpawiki-1.2.3/html_util.ml0000644000175000017500000001623611133415525016633 0ustar  jhellstenjhellsten(* Copyright (c) 2006-2008 Janne Hellsten  *)

(* 
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 2 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.  You should have received
 * a copy of the GNU General Public License along with this program.
 * If not, see . 
 *)

open XHTML.M

open Eliom_sessions
open Eliom_parameters
open Eliom_services
open Eliom_predefmod.Xhtml

open Lwt

open Config
open Types
open Services

let make_static_uri sp name =
  make_uri (static_dir sp) sp name

let disconnect_box sp s = 
  Eliom_predefmod.Xhtml.a ~service:disconnect_page ~sp [pcdata s] ()

(* Use this as the basis for all pages.  Includes CSS etc. *)
let html_stub sp ?(javascript=[]) body_html =
  let script src = 
    js_script ~a:[a_defer `Defer] ~uri:(make_static_uri sp src) () in
  let scripts  = 
    script ["nurpawiki.js"] :: (List.map script javascript) in
  html ~a:[a_xmlns `W3_org_1999_xhtml]
    (head
       (title (pcdata ""))
       ((scripts) @
          [css_link ~a:[] ~uri:(make_uri ~service:(static_dir sp) ~sp
                                  ["style.css"]) ();
           css_link ~a:[] ~uri:(make_uri ~service:(static_dir sp) ~sp
                                  ["jscalendar"; "calendar-blue2.css"]) ()]))
    (body body_html)

let is_guest user = 
  user.user_login = "guest"

let navbar_html sp ~cur_user ?(top_info_bar=[]) ?(wiki_revisions_link=[]) ?(wiki_page_links=[]) ?(todo_list_table=[]) content =
  let home_link link_text =
    a ~service:wiki_view_page 
      ~a:[a_accesskey 'h'; a_class ["ak"]] ~sp:sp link_text 
      (Config.site.cfg_homepage, (None, (None, None))) in
  let scheduler_link =
    a ~service:scheduler_page
      ~a:[a_accesskey 'r'; a_class ["ak"]] ~sp:sp 
      [img ~alt:"Scheduler" ~src:(make_static_uri sp ["calendar.png"]) ();
       pcdata "Scheduler"] () in
  let history_link =
    a ~service:history_page
      ~a:[a_accesskey 'r'; a_class ["ak"]] ~sp:sp 
      [img ~alt:"History" ~src:(make_static_uri sp ["home.png"]) ();
       pcdata "History"] None in

  let search_input =
    [get_form search_page sp
       (fun (chain : ([`One of string] Eliom_parameters.param_name)) -> 
          [p [string_input ~input_type:`Submit ~value:"Search" ();
              string_input ~input_type:`Text ~name:chain ()]])] in

  (* Greet user and offer Login link if guest *)
  let user_greeting = 
    pcdata ("Howdy "^cur_user.user_login^"!  ") ::
      if is_guest cur_user then
        [br(); br ();
         pcdata "To login as an existing user, click ";
         a ~a:[a_class ["login_link_big"]]~sp ~service:wiki_view_page 
           [pcdata "here"]
           (Config.site.cfg_homepage,(None,(None, Some true)));
         pcdata ".";
         br (); br ();
         pcdata "Guests cannot modify the site.  Ask the site admin for an account to be able to edit content."]
      else 
        [] in

  let disconnect_link sp = 
    if is_guest cur_user then [] else [disconnect_box sp "Logout"] in

  let my_preferences_link sp =
    if is_guest cur_user then 
      [] 
    else 
      [a ~service:edit_user_page ~sp [pcdata "My Preferences"]
         (None,cur_user.user_login)] in

  let edit_users_link = 
    if Privileges.can_view_users cur_user then
      [a ~service:user_admin_page ~sp [pcdata "Edit Users"] ()]
    else 
      [] in

  [div ~a:[a_id "topbar"]
     [table ~a:[a_class ["top_menu_size"]]
        (tr
           (td ~a:[a_class ["top_menu_left_align"]]
              [table
                 (tr (td [home_link 
                            [img ~alt:"Home" ~src:(make_static_uri sp ["home.png"]) ();
                             pcdata "Home"]])
                    [td [scheduler_link];
                     td [history_link];
                     td wiki_page_links])
                 []])
           [td ~a:[a_class ["top_menu_right_align"]]
              ([a ~service:about_page ~sp [pcdata "About"] ()] @
                 [pcdata " "] @
                 my_preferences_link sp @
                 [pcdata " "] @
                 edit_users_link @
                 [pcdata " "] @
                 disconnect_link sp)]) []]]
  @
    (if top_info_bar = [] then [] else [div ~a:[a_id "top_action_bar"] top_info_bar])
  @
    [div ~a:[a_id "navbar"]
       (user_greeting @ [br ()] @ search_input @ wiki_revisions_link @ todo_list_table);
     div ~a:[a_id "content"]
       content]

let error text = 
  span ~a:[a_class ["error"]] [pcdata text]

let error_page sp msg =
  html_stub sp 
    [p [error msg]]


let string_of_priority = function
    3 -> "lo"
  | 2 -> "med"
  | 1 -> "hi"
  | _ -> "INTERNAL ERROR: PRIORITY OUT OF RANGE"

let priority_css_class p =
  "todo_pri_"^(string_of_priority p)

(* Hash page description to a CSS palette entry.  Used to syntax
   highlight wiki page links based on their names. *)
let css_palette_ndx_of_wikipage page_id = 
  "palette"^(string_of_int (page_id mod 12))

let todo_page_links_of_pages sp ?(colorize=false) ?(link_css_class=None) ?(insert_parens=true) pages =
  let attrs page = 
    let color_css = 
      if colorize then [css_palette_ndx_of_wikipage page.p_id] else [] in
    match link_css_class with
      Some c -> [a_class ([c] @ color_css)]
    | None -> [a_class color_css] in
  let link page = 
    a ~a:(attrs page) ~service:wiki_view_page ~sp:sp [pcdata page.p_descr]
      (page.p_descr,(None,(None,None))) in
  let rec insert_commas acc = function
      (x::_::xs) as lst ->
        insert_commas (pcdata ", "::x::acc) (List.tl lst)
    | x::[] ->
        insert_commas (x::acc) []
    | [] -> List.rev acc in
  let insert_parens_html lst = 
    pcdata " ("::lst @ [pcdata ")"] in
  if pages <> [] then
    let lst = insert_commas [] (List.map link pages) in
    if insert_parens then 
      insert_parens_html lst
    else 
      lst
  else
    []

let todo_page_links sp todo_in_pages ?(colorize=false) ?(link_css_class=None) ?(insert_parens=true) id =
  let pages = try IMap.find id todo_in_pages with Not_found -> [] in
  todo_page_links_of_pages ~colorize sp pages

let todo_edit_img_link sp page_cont task_id =
  [a ~a:[a_title "Edit"] ~service:edit_todo_get_page ~sp:sp
     [img ~alt:"Edit" 
        ~src:(make_static_uri sp ["edit_small.png"]) ()]
     (page_cont, Some task_id)]

let complete_task_img_link sp task_id =
  let img_html = 
    [img ~alt:"Mark complete" 
       ~src:(make_static_uri sp ["mark_complete.png"]) ()] in
  a ~service:task_side_effect_complete_action
    ~a:[a_title "Mark as completed!"] ~sp img_html task_id

let todo_descr_html descr owner = 
  match owner with
    None -> [pcdata descr]
  | Some o ->
      [pcdata descr; 
       span ~a:[a_class ["todo_owner"]] [pcdata (" ["^o.owner_login^"] ")]]


(* Use to create a "cancel" button for user submits *)
let cancel_link service sp params =
  a ~a:[a_class ["cancel_edit"]] ~service:service ~sp:sp 
    [pcdata "Cancel"] 
    params