Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

* Initial commit for Stackato Sample App Contest.

  • Loading branch information...
commit a94b5569be275849ec13244078b438e51a733534 0 parents
@audreyt authored
Showing with 29,281 additions and 0 deletions.
  1. +685 −0 Changes.txt
  2. +72 −0 LEGAL.txt
  3. +705 −0 LICENSE.txt
  4. +32 −0 README
  5. +189 −0 app.coffee
  6. +295 −0 app.js
  7. +950 −0 formatnumber2.js
  8. +4,749 −0 formula1.js
  9. BIN  images/sc-1x1.gif
  10. BIN  images/sc-aligncenter.gif
  11. BIN  images/sc-alignleft.gif
  12. BIN  images/sc-alignright.gif
  13. BIN  images/sc-bordersoff.gif
  14. BIN  images/sc-borderson.gif
  15. BIN  images/sc-chooserarrow.gif
  16. BIN  images/sc-commentbg.gif
  17. BIN  images/sc-copy.gif
  18. BIN  images/sc-cursorinsertleft.gif
  19. BIN  images/sc-cursorinsertup.gif
  20. BIN  images/sc-cut.gif
  21. BIN  images/sc-defaultcolor.gif
  22. BIN  images/sc-delete.gif
  23. BIN  images/sc-deletecol.gif
  24. BIN  images/sc-deleterow.gif
  25. BIN  images/sc-divider1.gif
  26. BIN  images/sc-drag-handles.gif
  27. BIN  images/sc-drag-handles.png
  28. BIN  images/sc-endcap-h.gif
  29. BIN  images/sc-endcap-v.gif
  30. BIN  images/sc-filldown.gif
  31. BIN  images/sc-fillright.gif
  32. BIN  images/sc-formuladialog.gif
  33. BIN  images/sc-insertcol.gif
  34. BIN  images/sc-insertrow.gif
  35. BIN  images/sc-less-hd.gif
  36. BIN  images/sc-less-hh.gif
  37. BIN  images/sc-less-hn.gif
  38. BIN  images/sc-less-vd.gif
  39. BIN  images/sc-less-vh.gif
  40. BIN  images/sc-less-vn.gif
  41. BIN  images/sc-linkdialog.gif
  42. BIN  images/sc-linkout.gif
  43. BIN  images/sc-logo.gif
  44. BIN  images/sc-main-h.gif
  45. BIN  images/sc-main-v.gif
  46. BIN  images/sc-merge.gif
  47. BIN  images/sc-more-hd.gif
  48. BIN  images/sc-more-hh.gif
  49. BIN  images/sc-more-hn.gif
  50. BIN  images/sc-more-vd.gif
  51. BIN  images/sc-more-vh.gif
  52. BIN  images/sc-more-vn.gif
  53. BIN  images/sc-movefrom.gif
  54. BIN  images/sc-movefromoff.gif
  55. BIN  images/sc-moveinsert.gif
  56. BIN  images/sc-moveinsertoff.gif
  57. BIN  images/sc-movepaste.gif
  58. BIN  images/sc-movepasteoff.gif
  59. BIN  images/sc-multilinedialog.gif
  60. BIN  images/sc-paneslider-h.gif
  61. BIN  images/sc-paneslider-v.gif
  62. BIN  images/sc-paste.gif
  63. BIN  images/sc-pasteformats.gif
  64. BIN  images/sc-peerbg.gif
  65. BIN  images/sc-range2.gif
  66. BIN  images/sc-recalc.gif
  67. BIN  images/sc-redo.gif
  68. BIN  images/sc-scrollarea-h.gif
  69. BIN  images/sc-scrollarea-v.gif
  70. BIN  images/sc-sumdialog.gif
  71. BIN  images/sc-swapcolors.gif
  72. BIN  images/sc-thumb-hd.gif
  73. BIN  images/sc-thumb-hh.gif
  74. BIN  images/sc-thumb-hn.gif
  75. BIN  images/sc-thumb-vd.gif
  76. BIN  images/sc-thumb-vh.gif
  77. BIN  images/sc-thumb-vn.gif
  78. BIN  images/sc-trackingline-h.gif
  79. BIN  images/sc-trackingline-v.gif
  80. BIN  images/sc-undo.gif
  81. BIN  images/sc-unmerge.gif
  82. BIN  images/sc-wikiflag.gif
  83. BIN  images/sc-wikilinkflag.gif
  84. +20 −0 index.css
  85. +366 −0 index.mt
  86. +9 −0 package.json
  87. +1 −0  requirements.txt
  88. +5,804 −0 socialcalc-3.js
  89. +62 −0 socialcalc.css
  90. +818 −0 socialcalcconstants.js
  91. +1,618 −0 socialcalcpopup.js
  92. +685 −0 socialcalcserver.pl
  93. +3,585 −0 socialcalcspreadsheetcontrol.js
  94. +6,404 −0 socialcalctableeditor.js
  95. +687 −0 socialcalcviewer.js
  96. +80 −0 socketpolicy.pl
  97. +122 −0 start.css
  98. BIN  static/img/davy/bg/home2.png
  99. BIN  static/img/davy/bg/product.png
  100. BIN  static/img/davy/btn/createpad-home.gif
  101. BIN  static/img/davy/gfx/home-logo2.gif
  102. BIN  static/img/davy/gfx/home-logo2.png
  103. BIN  static/img/davy/gfx/screenshot.png
  104. +191 −0 third-party/class-js/README
  105. +117 −0 third-party/class-js/lib/Class.js
  106. +521 −0 third-party/wikiwyg/LICENSE
  107. +22 −0 third-party/wikiwyg/lib/Document/Emitter.js
  108. +23 −0 third-party/wikiwyg/lib/Document/Emitter/ByteCode.js
  109. +92 −0 third-party/wikiwyg/lib/Document/Emitter/HTML.js
  110. +175 −0 third-party/wikiwyg/lib/Document/Parser.js
  111. +202 −0 third-party/wikiwyg/lib/Document/Parser/Wikitext.js
685 Changes.txt
@@ -0,0 +1,685 @@
+Changes
+
+2007-12-27:
+Fixed missing 'nl' entry in typelookup plus entry. (=false+1 was failing)
+Renamed scjstest to socialcalc-1.js.
+Added load and save of sheetobj.names.
+Added names to data sent by simpleedit to server.
+
+2008-01-02:
+Added ExecuteSheetCommand with "set sheet" commands.
+Added GetStyleNum.
+Added Parse class.
+Added UndoStack class.
+
+2008-01-03:
+Added Undo/Redo and implemented it for set sheet commands.
+
+2008-01-04:
+Started set cell commands.
+
+2008-01-07:
+Split undo into PushChange, AddDo, and AddUndo.
+Added CellFromStringParts and CellToString and "set coord all".
+Added more set cell commands.
+Added EditorApplySetCommandsToRange.
+
+2008-01-08:
+Fixed bug with clicking on cell below stuff not rendered yet.
+
+2008-01-11:
+Added more set commands
+
+2008-01-14:
+Moved to SocialCalcJSv2 hierarchy for revision control
+Changed programs to use new hierarchy, e.g., image/ and data/
+
+2008-01-15,16,17,18:
+Created formula1.js to parse and execute formulas.
+Added start of RecalcSheet to socialcalc-2.js.
+
+2008-01-21:
+Implemented function scaffolding.
+Added range support to formulas.
+Implemented series functions, including SUM, etc.
+Fixed OLPC Fn key bug.
+
+2008-01-23:
+SocialCalc2Demo command/slist control.
+Better keyboard focus handling when document window loses focus (passThru).
+Added Home key to MoveECellWithKey.
+Added multi-line to ExecuteSheetCommand, Parse class.
+
+2008-01-24:
+Built SocialCalc2Demo tabs: Plain, Source, Help, About
+
+2008-01-26:
+Added IF(condition,true-value,false-value) function.
+Added erase All/Contents/Formats command.
+Added filldown and fillright commands and SocialCalc.OffsetFormulaCoords.
+Released Sweet SocialCalc 0.1.
+
+2008-01-28:
+Changed order of display on Show Source/doNewSheet for iPhone bug.
+Added Math1 functions: ABS, ACOS, ASIN, ATAN, COS, DEGREES, EVEN, EXP, FACT, INT,
+ LN, LOG10, ODD, RADIANS, SIN, TAN
+Added ZeroArgFunctions: FALSE(), NA(), NOW(), PI(), TODAY(), TRUE()
+Added Math2Functions: ATAN2, MOD, POWER, TRUNC
+
+2008-01-30:
+Removed uses of "for (i in arrayobj)" for Prototype, etc., compatibility
+
+2008-01-31:
+Added clipboard to sheet, as well as to save/load sheet
+Bumped save version to 1.4
+Added copy, cut, paste, loadclipboard, clearclipboard commands
+Added clipboard to Sweet SocialCalc source tab, with undo
+
+2008-02-02:
+Made clipboard global to SocialCalc object.
+Updated simpleedit8.pl to have command list of socialcalc2demo1
+
+2008-02-05:
+Added merge and unmerge commands.
+Added insertcol/row commands.
+
+2008-02-06:
+Added deletecol/row commands.
+Added special values to formula parsing, like #REF!.
+
+2008-02-07:
+Added licensing information, breaking out socialcalctableeditor.js.
+Released as version 0.6.
+
+2008-02-08:
+Changed URLs to be specific for About details and Attribution.
+Bumped to 0.6.1
+
+2008-02-09:
+Removed substr(-numbers), which are not handled correctly by IE, in formula1.js, formatnumber2.js.
+Fixed a bug with "+coord" - changed "sheetdata" to "sheet".
+
+2008-02-10:
+Made UI Sugar-like with more tabs, grayscale scrollbars.
+
+2008-02-11:
+Added ConvertSaveToOtherFormat and ConvertOtherFormatToSave to give multiple clipboard views
+
+2008-02-13:
+Added sort command.
+
+2008-02-14:
+Add primitive graph command.
+
+2008-02-15:
+Released 0.6.3.
+
+2008-02-18:
+Fixed sort "constant" bug which left a numeric constant (vtc) treated as text, not a number
+Added SocialCalc.TestCriteria.
+
+2008-02-19:
+Added DAVERAGE, DCOUNT, DCOUNTA, DGET, DMAX, DMIN, DPRODUCT, DSTDEV, DSTDEVP, DSUM, DVAR, and DVARP.
+Added HLOOKUP, VLOOKUP, MATCH, INDEX, COUNTIF, and SUMIF.
+
+2008-02-21:
+Added the rest of the wikiCalc/SocialCalc 1.1 normal functions.
+
+2008-03-10:
+Replaced cursor use of editor.ReplaceCell with editor.UpdateCellCSS for speedup.
+
+2008-03-12:
+Made 702 maximum number of columns (ZZ) for number to characters.
+
+2008-03-14:
+First implementation of socialcalcspeadsheetcontrol.js.
+
+2008-03-20:
+Fixed up name support in formulas, including getting names defined by formulas working.
+
+2008-03-24:
+Added SocialCalc.Formula.loadsheet for inter-sheet references.
+
+2008-03-25:
+Added comment value to cells.
+Finished other places that were waiting for names or sheet references.
+
+2008-03-27:
+Added SaveEditorSettings and LoadEditorSettings.
+
+2008-04-01:
+Added tabs and views lists to SpreadsheetControl.
+Tried rudimentary "audit" tab.
+
+2008-04-03:
+Finished audit tab and comment tab.
+
+2008-04-04:
+Changed formula parsing to allow "." inside alpha and made "_" alpha.
+Added name commands to socialcalc-3.js.
+Started and Names tab.
+
+2008-04-05:
+Finished Names tab.
+
+2008-04-07:
+Added SpreadsheetControlCreateSpreadsheetSave and DecodeSpreadsheetSave,
+along with multipart-mime save format.
+Fixed SocialCalc.SizeSSDiv: this.requestedHeight/Width => spreadsheet.requested...
+
+2008-04-09:
+Moved the Audit, Comment, and Names tab definition code into socialcalcspreadsheetcontrol.js.
+Added linkstyle to RenderSheet, carried through RenderCell, passed to expand_markup.
+Added text formats to list (plain, HTML, wiki, hidden), fixed bug with default text format.
+Parameterized toolbarbackground and tabbackground.
+
+2008-04-10:
+Fixed bug introduced with linkstyle in rendering with linkstyle!=null.
+Changed names of determine_value_type and format_value_for_display to camel case:
+ DetermineValueType and FormatValueForDisplay.
+Added Clipboard tab and view to facilitate interim moving of data from Excel and web.
+
+2008-04-13:
+Fixed requestedHeight/Width not working in SpreadsheetControl.
+
+2008-04-14:
+Changed rowneedsrefresh in scroll up/down one row to be object instead of array for Prototype compatibility.
+Added SocialCalc.SpreadsheetControlCreateCellHTML and SocialCalc.SpreadsheetControlCreateCellHTMLSave.
+
+2008-04-16:
+Fixed SocialCalc.Formula.OperandAsSheetName not handling coords and names to get sheet name.
+
+2008-04-17:
+Keyboard handing: Fixed initial "[" being ignored, backspace passing through to browser at top level (now treated as delete).
+Fixed sheetname!range_name not working and numerous other sheetname! bugs.
+Fixed handling of space after coord in formula.
+If SocialCalc.Formula.SheetCache.loadsheet returns null, an error is displayed in addition to #REF!.
+
+2008-04-18:
+Added dorecalc argument to SocialCalc.ConvertSaveToOtherFormat.
+
+2008-04-21:
+Added editor.SettingsCallbacks.
+Added named ranges to Sort.
+
+2008-04-23:
+Added SocialCalc.defaultvalues.minimumcolwidth.
+Added column drag resizing.
+Fixed bug with dragging cursor out of grid losing capture on Firefox and Safari.
+
+2008-04-24:
+Made drag resize display work in Opera.
+Removed dependency on body setting for font-size:small.
+Added more button bar buttons: Reverse, Wiki Text, Align, etc.
+Added spreadsheet control ExportCallback.
+
+2008-04-25:
+Fixed thumbstatus font size.
+More drag resize for Opera and Firefox 3.
+
+2008-04-26:
+Fixed merge button bug.
+Added check to guard against drag resizing non-visible columns.
+
+2008-04-30:
+Created SocialCalc.Constants.
+Fixed bug where circularreferencecell wasn't reset on new recalc.
+
+2008-05-01:
+Fixed bug where merged cells' grid hid borders to right and below.
+Fixed horizontal control position off when not Verdana bug.
+
+2008-05-02:
+Added more SocialCalc.Constants.
+Added optional IDs on table control elements.
+Fixed double-click outside grid bug.
+
+2008-05-04:
+Added optional styles for table control elements.
+Moved table control repeat settings to constants.
+Made thumbstatus settings skinnable with constants.
+
+2008-05-05:
+More constants: The rest of socialcalctableeditor.js, formatnumber2.js, and some of formula1.js.
+
+2008-05-06:
+More constants: The rest of formula1.js and HighlightTypes for cursor and range.
+Fixed recent bug with unable to click inside of input box.
+Fixed -1 1/2 => -0.5 bug.
+
+2008-05-09:
+Mostly finished InputBox/InputEcho stuff.
+Fixed SocialCalc.intFunc bug which led to 2/3/08 (all Feb) being wrong.
+
+2008-05-11:
+Fixes some "event" references that should have been "e" in socialcalctableeditor.js.
+Made InputEcho draggable.
+Added SocialCalc.ResizeTableEditor.
+
+2008-05-12:
+Finish up InputBox stuff, handling no change, clicking during partialexpr, etc.
+Added editor.DisplayCellContents() to be used to keep formula bar up to date
+Fixed some bugs with reporting errors in formulas detected during parsing
+
+2008-05-13:
+Fixed a focus outside the table editor bug with the input box.
+Added ID to inputEcho.
+
+2008-05-20:
+Continued work on SettingsControls objects, including adding the ColorDropdown and CustomDropdown.
+Fixed some bugs with sizing of the non-main views.
+
+2008-05-21,22:
+Completed Settings view display of existing settings.
+Started GetValues and DecodeSheetSettings
+
+2008-05-26:
+Implemented BorderSides settings control
+Connected DecodeCellSettings, etc., so Settings view works
+Layouts now handle * in any value position (PrecomputeSheetFonts renamed to PrecomputeSheetFontsAndLayouts)
+
+2008-05-28:
+Added SocialCalc.EditorMouseInfo.ignore to turn off mousedown and dblclick detection temporarily.
+Added defaultCommentClass, defaultCommentStyle, defaultCommentNoGridClass, and defaultCommentNoGridStyle
+ to Constants for SocialCalc.RenderCell and context.commentClassName,
+ context.commentClassCSS, etc., to RenderContext.
+Created SocialCalc.ConstantsDefaultClasses and socialcalc.css.
+
+2008-06-02:
+Added buttons to socialcalcspreadsheetcontrol.js.
+Reworked the default toolbars to use buttons with icon images added to images file.
+Made Clipboard tab have multiple formats again.
+Updated the Help tab text.
+
+2008-06-04:
+Fixed problem with * in font in EncodeCellAttributes
+
+2008-06-07:
+Made InputBox Firefox up/down arrow handling work in more cases, adding inputBox.skipOne
+Fixed H/VLOOKUP functions ignoring the rangelookup value
+
+2008-07-07:
+Fixed blowup bug with "1 1/3" in SocialCalc.DetermineValueType
+
+2008-07-08:
+EditorRenderSheet now adds "fullgrid" as an element id. It's the element that gets sheet mouse clicks.
+
+2008-07-09:
+Fixed missing "1,234.5" format.
+
+2008-07-17:
+Added statusline callbacks.
+Added more comments about SocialCalc.Cell.
+Changed SocialCalc.CellFromStringParts to convert strings to numbers in vt, vtf, and vtc.
+Fixed bug where vertical-align wasn't being enforced in SocialCalc.SetECellHeaders.
+Redid keyboard handlers to follow http://unixpapa.com/js/key.html more,
+ fixing bugs with Safari 3.1 and Opera 9.5.
+Changed SocialCalc.InputBoxOnClick to SocialCalc.InputBoxOnMouseDown (bug 796).
+
+2008-07-18:
+SocialCalc.DetermineValue now handles multiple commas (had missing "g" attribute) (bug 805).
+
+2008-07-29:
+SocialCalc.Formula.SheetCache upgraded to handle loading, status values, and recalc flags.
+New recalc code:
+ Fixed: Remember to have UI check for circ references and display status
+ Fixed: =Self should be circ
+ Fixed: if calced value/type is the same, don't delete display value
+
+2008-09-09:
+Fixed formatnumber2.js ampmstr using non-existant constants
+
+2008-09-10:
+Moved CalculateColWidthData call into RenderSheet
+Fixed bug with last two rows in pane not getting height calculations updated correctly in
+ CalculateEditorPositions
+Removed SheetRenders before recalc
+
+2008-09-11:
+Fixed bug with pane slider into scrolled row/col too far: now it unscrolls second pane
+ (but must wait for position recalc, unfortunately)
+
+2008-09-12:
+Fixed bug that kept pan slider tracking lines from showing
+
+2008-09-18:
+EditorSaveEdit now does encodeForSave of text.
+Added sheet.renderneeded and sheet.celldisplayneeded
+Added SocialCalc.ScheduleSheetCommands and started using it instead of ExecuteCommands directly
+
+2008-09-19:
+ScheduleSheetCommands now starts a time-sliced loop to execute commands
+
+2008-09-20:
+2008-09-21:
+2008-09-22:
+2008-09-23:
+Made commands, recalc, and display all be timer driven
+Added deferred command execution
+Added edit.busy
+Made most of UI observe the busy flag, including Button and Drag additions
+
+2008-11-06:
+Added calcorder as a timesliced part of recalc.
+
+2008-11-07:
+Added recalc to coded and decoded sheet attributes.
+Sheet recalc attribute is now followed, as well as new sheet.recalconce.
+
+2008-11-10:
+SpreadsheetControl now has a default status line.
+Added recalc button to toolbar.
+
+2008-11-11:
+Recalc is now followed in mult-sheet recalc.
+
+2008-11-14:
+Tab switching is ignored away from sheet when editor.busy.
+Initial spreadsheet.currentTab is now 0 after initialization.
+Recalc button in toolbar is only displayed if recalc needed
+
+2008-11-15:
+Made spreadsheet.DoOnResize.
+Fixed bug with ResizeTableEditor changing griddiv but not toplevel.
+
+2008-11-16:
+Made SocialCalc.ResetSheet only reset data stuff so Reload works in new event-driven world.
+
+2008-11-19:
+Sort range is now saved and loaded.
+
+2008-11-24:
+Added sheet.changedrendervalues to fix bugs with changed fonts, etc.
+Added color chooser to settings tab
+Made scroll wheel follow editor.busy
+
+2008-11-26:
+Updated simpleedit14.pl
+Fixed some IE bugs with SocialCalc.SpreadsheetControlDecodeSpreadsheetSave with ^$
+
+2008-11-29:
+Fixed row hide setting load bug (typo).
+
+2008-12-01:
+Made simpleedit14.pl do server-side wikitext expansion differently than client-side.
+Fixed bug with formula bar not being updated after commands (and at load).
+Fixed bug with commands being executed during cell edit.
+
+2008-12-04:
+Made General format round to a maximum precision to lessen floating point artifacts.
+
+2008-12-09:
+Added editor.ctrlkeyFunction, including Ctrl-V handling.
+Added embedded newline support to csv and tab format conversion.
+
+2008-12-10:
+Fixed bugs in simpleedit14.pl with loading unavailable sheets
+
+2008-12-11:
+Added undo maximum of 100.
+
+2008-12-26:
+Fixed SocialCalc.setStyles to allow colons in style values. (kratib reported)
+Finally fixed FF 2 Mac losing Ctrl-V.
+Changed grid line and pane divider color to something darker to better work on some laptops.
+Fixed some bugs with sort settings not being preserved when updating column chooser info or loading
+
+2008-12-28:
+Fixed some bugs with displaying zero values related to infinity and NaN.
+
+2009-01-14:
+Fixed bug with reloading sheet with font settings.
+
+2009-01-15:
+First implementation of movepaste/moveinsert done.
+Added swapcolors button to socialcalcspreadsheetcontrol.js.
+
+2009-02-02:
+Changed to SocialCalc.Callbacks.expand_wiki which takes subtypes.
+Implemented demo samples of text-wiki-pagelink.
+
+2009-02-05:
+Added SocialCalc.Formula.RemoteFunctionInfo.waitingForServer to help handling RPC.
+Fixed recalc off not recalculating positions in case cell got different size.
+
+2009-02-20:
+Created socialcalcpopup.js and changed socialcalcspreadsheetcontrol.js to use it.
+
+2009-02-24:
+Continued fixing bugs in socialcalcpopup.js and adding features.
+
+2009-02-25:
+Moved spreadsheetcontrol button and tab styles to SocialCalc.Constants to make skinning easier.
+
+2009-03-10:
+Made socialcalc2demo10.
+Made socialcalcserver.pl use all filenames and have settings file.
+
+2009-03-19:
+Added function arg_def, func_def, and func_class to formula1.js and socialcalcconstants.js.
+Added definitions to all functions.
+Added function information routines FillFunctionInfo and FunctionArgString.
+Added prompt to InputEcho to show function argument prompts.
+Added function list dialog to ssctrltest1.html.
+Added SocialCalc.EditorAddToInput for pasting function starts, etc.
+
+2009-03-23:
+Added formula bar buttons to socialcalcspreadsheetcontrol.js.
+Moved function list as a formula bar button in socialcalcspreadsheetcontrol.js.
+Added Multi-line input box dialog and support.
+
+2009-03-24:
+Tuned multi-line input to handle disabling inputbox when editing and when multi-line cell content.
+Added SocialCalc.Formula.FreshnessInfo to help determine if calculations are out of date.
+
+2009-04-01:
+Fixed bug with maxUndo that messed up audit. Now have maxRedo, too.
+
+2009-04-15:
+Added value type "tl" -- text link
+Upgraded text-link format handing, and added SocialCalc.ParseCellLinkText and .expand_text_link.
+Made better handling of linktype (socialcalcspreadsheetcontrol.js) and $options (SocialCalcServersideUtilities.pm)
+
+2009-04-16:
+More work on text-link and added to SocialCalcServersideUtilities.pm.
+
+2009-04-29:
+Made linkstyle an object, added context.defaultlinkstyle and context.defaultHTMLlinkstyle.
+HTML rendering stuff like SpreadsheetControlCreateCellHTML take optional linkstyle or use defaultHTMLlinkstyle.
+Linking now has [pagename] and {worksheet [pagename]}/
+Added SocialCalc.Callback.MakePageLink.
+
+2009-04-30:
+Added Link dialog.
+
+2009-05-01:
+Added set format and popup options to Link dialog.
+Upgraded SocialCalcServersideUtilities.pm to handle pagenames and workspaces.
+
+2009-05-07:
+Added SocialCalc.GetElementPositionWithScroll to socialcalc-3.js to fix Popup bug when settings pane scrolled.
+Added sheet.recalcchangedavalue so you can tell if a recalc changed anything.
+
+2009-05-11:
+Changed tableeditor, socialcalc-3.js, and spreadsheetcontrol to use SocialCalc.Constants.defaultImagePrefix for images. It should have the "sc-" in it.
+SocialCalc.Popup.imagePrefix needs its own version of the same thing.
+
+2009-05-15:
+Split SocialCalcServersideUtilities.pm into 2 parts, adding SocialCalcServersideNumberFormatting.pm.
+Upgraded socialcalcserver.pl to handle new image prefixes.
+Added /* */ to SocialCalc js files so the minimizer won't strip out the licensing notices.
+
+2009-05-16:
+Added ctrl-c handling, and got ctrl-c/ctrl-v working on FF 2/3/mac, Safari/Chrome, IE 6/7, Opera.
+Added ctrl-z to do undo.
+Fixed maxUndo/maxRedo to have maxRedo be the max size of stack and maxUndo is max undoable, and various undo bugs.
+Fixed bugs with queuing up commands.
+Set default maxUndo to 50.
+Fixed bug that made some typeahead be lost.
+Changed statusline total to use formatNumberWithFormat with [,]General format to clean up rounding, and add commas.
+
+2009-05-17:
+Changed Ctrl-V to do just a Paste Formulas, not Paste All.
+
+2009-05-18:
+Added Ctrl-X to be like Ctrl-C with Cut formulas instead of copy, made Ctrl-C use EditorScheduleSheetCommands.
+
+2009-05-19:
+Hide ssctrl1.html extra buttons, added sample minimal Sum and Sum2 Button code.
+Updated EditorAddToInput to erase any pointing partial expressions.
+
+2009-05-21:
+Changed ctrl-v to paste in upper left if has range.
+
+2009-05-22:
+Changed dragging vertical thumb to display part of each proposed new top row. New constants, etc.
+
+2009-05-28:
+Wrote CreateCSV routine in Perl in socialcalcserverX.pl.
+
+2009-05-31:
+Moved sum button into socialcalcspreadsheetcontrol.js as additional formula bar button.
+
+2009-06-01:
+Made OLPC version's graphing more modular, and save.
+Fixed bug in sort settings save.
+Added SocialCalc.Callbacks.NormalizeSheetName to socialcalc-3.js and formula1.js.
+Moved CreateCSV into SocialCalcServersideUtilities.pm.
+
+2009-06-09:
+Fixed Safari bug with detecting partial formulas for prompt.
+Fixed bugs with conditionals in formats. Issues converting from Perl...
+Merged SocialCalcServersideFormatting.pm back into ServersideUtilities.pm.
+Fixed bug in js and Perl with missing "=" comparison in conditional custom formats.
+Added temporary Ctrl-S for setting custom numeric formats.
+
+2009-06-11:
+Added "cmd:" prefix option to Ctrl-S for manually issuing commands.
+Fixed bug in VLOOKUP argument prompt.
+
+2009-06-14:
+Fixed bug with SocialCalc.Formula.OperandAsSheetName not working with absolute references.
+Fixed bug with Popup custom not escaping current value.
+
+2009-06-16:
+Fixed bug in SocialCalc.RecalcCheckCell where sheetref wasn't reset if range item ended in sheetref.
+
+2009-06-21:
+Fixed: Audit tab doesn't escape <>, etc.
+
+2009-06-28:
+Fixed bug with text-custom not working (conversion from Perl...)
+
+2009-07-15:
+Fixed INDEX function not handling references on another sheet.
+
+2009-07-21:
+Fixed redo of name delete setting value to description.
+
+2009-08-17:
+Moved "moveecell" status call up above editor.EnsureECellVisible to not overwrite "Displaying..." message on Home, etc.
+Fixed bug with Link dialog pasting page references adding extra "]".
+Added SocialCalc.Popup.LocalizeString that needs to be overridden in socialcalcpopup.
+
+2009-08-19:
+Fixed bug with socialcalcpopup.js Color Chooser when you clicked on last pixels of grid.
+Added SocialCalc.LocalizeString and SocialCalc.LocalizeSubstrings to socialcalcspreadsheetcontrol.js.
+Made use of LocalizeString and LocalizeSubstrings in socialcalcspreadsheetcontrol.js, ssctrltest1.html, OLPC code, etc.
+This should finish the main localization enablement of SocialCalc in JavaScript.
+
+2009-08-27:
+Removed extra " in SocialCalcServersideUtilities.pm that was messing up spans, etc.
+
+2009-09-03:
+Put in SocialCalc.CanonicalizeSheet to do a pass before save to minimize sheet extents, remove unused items from
+saved lists and alphabetize them. The saved data is upwards and downwards compatible.
+Added SocialCalc.Constants.doCanonicalizeSheet to turn this off.
+
+2009-09-09:
+Added sampleWidth, sampleHeight, backgroundImage, backgroundImageDefault, and backgroundImageDisabled to color chooser attribs.
+
+2009-09-23:
+Added ensureWithin to socialcalcpopup.js.
+Changed cursor position detection a bit in color chooser.
+Made border color chooser moveable.
+Fixed "-", ".", "e1" and other things being considered a number on input.
+
+2009-10-21:
+Added text subtype "tr" (text rich) to formula1.js TypeLookupTable and to socialcalc3.js format_text_for_display
+
+2009-11-02:
+Minor change to SocialCalc.special_chars to clean up regex. Not a bug, but a minor performance thing.
+
+2009-11-03:
+Added text format Wikitext to SCFormatTextFormats in socialcalcconstants.js
+
+2009-12-02:
+Added missing // to socialcalcspreadsheetcontrol.js setting of tabBackground.
+Set minOK to 0 just in case in formatnumber2.js.
+
+2010-01-14:
+Changed socialcalctableeditor.js to do auto-repeat in drag select.
+Made formula editing reset position of InputEcho after pointing in case cell position has changed.
+Added beginning of SocialCalc.CellHandles to socialcalctableeditor.js. Had test code, but now just returns.
+
+2010-02-09:
+Fixed bug where undo stack didn't always set changedrendervalues so moves/pastes/etc of merged cells messed up display
+
+2010-03-23:
+Finished changes to add editor.noEdit to socialcalctableeditor.js, including
+fixing thumb dragging to better handle mouse out of window, handling no socialcalcspreadsheetcontrol.js,
+etc.
+
+2010-03-25:
+Added socialcalcviewer.js.
+Fixed bug in SocialCalc.InitializeSpreadsheetControl that didn't take padding into account when sizing status line.
+
+2010-04-13:
+Added CmdExtensions to socialcalc-3.js, and the startcmdextension command.
+
+2010-05-07:
+Implemented drag handles for fill/move using a single image with a round, segmented palette. Added sc-drag-handles.png.
+
+2010-05-12:
+Added SocialCalc.CtrlSEditor to socialcalctableeditor.js and socialcalcspreadsheetcontrol.js.
+Use "edit:partname" command to edit, "edit:" to list all parts and contents. No text deletes part.
+Added SocialCalc.OtherSaveParts to socialcalcspreadsheetcontrol.js.
+This all gives us a way to set startup macros, etc.
+
+2010-05-13:
+Fixed IE6 and IE7+ compatibility issues with drag palette. Uses .gif for IE6, .png otherwise.
+
+2010-07-05:
+Upgraded to Tracy's drag palette images, including making radii setable constants.
+Made click without drag on drag palette not do any commands.
+Put in a fix for Safari 5 problem with copy/paste (involving onbeforepaste default behavior).
+
+
+TO DO:
+
+Check out <= and >= Test Criteria!
+
+Make defaultCommentStyle work with defaultImagePrefix.
+
+Handle bad settings
+Make sure insert/delete row/col and move handle name coord changing undo, especially wrt #REF!.
+Need some way to abort recalc -- like pressing Esc?
+
+
+Limit undo size?
+1 row scroll of high cells doesn't update row height values or something -
+ scroll in Merges and Scrolling when 2 panes -- may be dragging when scrolled
+ doesn't know trying to set too far: check test
+Bug in SocialCalc.pm: adjust_formula_coords refs to deleted cells -- doesn't handle multiple
+Bug in Sheet.pm: test_criteria tests "value" instead of "type" for left error
+Check SheetFunctions.pm: Dseries with criteria of "0" -- checks for blank as !criteria, not length
+ Also, see double testcol setting.
+INDEX function (and range return from evaluate polish) does not handle other sheets.
+ Make DecodeRangeParts get that stuff to make it easy?
+Bug in SheetFunctions.pm: StringFunctions error doesn't return right away
+ RIGHT has -1 args?
+ InterestFunctions: should be -3 args?
+ IRR check for values?
+Bug in Sheet.pm: evaluate_parsed_formula return of range doesn't swap sheetname!coord
+Sheet.ResetSheet doesn't seem to work well -- it does not recalc or redisplay well afterward
+
72 LEGAL.txt
@@ -0,0 +1,72 @@
+SOCIALCALC LEGAL.txt FILE:
+
+LEGAL INFORMATION
+
+This LEGAL.txt file accompanies the SocialCalc program. It includes notices required by the
+licenses as well as general legal notices.
+
+=========================================
+ COPYRIGHT AND ATTRIBUTION NOTICES
+=========================================
+
+Copyright (C) 2009 Socialtext, Inc.
+All Rights Reserved.
+
+image:sc-logo.gif
+"SocialCalc"
+http://www.socialcalc.org/xoattrib
+
+=========================================
+ SOURCE CODE AVAILABILITY NOTICE
+=========================================
+
+The source code for this product is available from:
+http://socialcalc.org/.
+
+=========================================
+ GENERAL LEGAL NOTICES
+=========================================
+
+wikiCalc, Garden, and Software Garden are registered trademarks of Software Garden, Inc.
+Socialtext and SocialCalc are registered trademarks of Socialtext, Inc.
+The Socialtext logo and Dreamcatcher are trademarks of Socialtext, Inc.
+
+=========================================
+ LEGAL NOTICES REQUIRED BY THE LICENSE
+=========================================
+
+CHANGES MADE TO THE COVERED CODE (see CPAL Version 1.0 Section 3.3):
+
+2008-02-08:
+ Original Code started as a translation to JavaScript of code in SocialCalc 1.1.0 plus
+ much new code.
+
+ Python code for the OLPC XO-1 initially coded by Luke Closs of Socialtext, Inc.
+
+ JavaScript initially coded by Dan Bricklin of Software Garden, Inc., for Socialtext, Inc.
+ Based in part on the SocialCalc 1.1.0 code written in Perl.
+ The SocialCalc 1.1.0 code was:
+ Portions (c) Copyright 2005, 2006, 2007 Software Garden, Inc.
+ All Rights Reserved.
+ Portions (c) Copyright 2007 Socialtext, Inc.
+ All Rights Reserved.
+ The Perl SocialCalc started as modifications to the wikiCalc(R) program, version 1.0.
+ wikiCalc 1.0 was written by Software Garden, Inc.
+ Unless otherwise specified, referring to "SocialCalc" in comments refers to this
+ JavaScript version of the code, not the SocialCalc Perl code.
+
+----------
+
+(Documentation of future changes as the result of Modifications, including the date of
+change, will go here in this LEGAL.txt file. This documentation may be summaries of
+changes with the more detailed descriptions included in the actual modified files as
+appropriate.)
+
+==========
+
+THIRD PARTY CLAIMS (see CPAL Version 1.0 Section 3.4(a)):
+
+None.
+
+[End of LEGAL.txt]
+
705 LICENSE.txt
@@ -0,0 +1,705 @@
+SOCIALCALC LICENSE.txt FILE:
+
+=========================================
+ ABOUT THIS FILE
+=========================================
+
+This file includes copies of the Common Public Attribution License (CPAL) and
+the Artistic License 2.0.
+
+This product consists of components licensed under different licenses.
+Check the contents of each file for a statement of the license for that file.
+Files without license information are licensed under the Artistic License 2.0.
+
+======================================================
+ COMMON PUBLIC ATTRIBUTION LICENSE VERSION 1.0 (CPAL)
+======================================================
+
+Common Public Attribution License Version 1.0 (CPAL)
+
+1. "Definitions"
+
+1.0.1 "Commercial Use" means distribution or otherwise making the Covered Code
+available to a third party.
+
+1.1 "Contributor" means each entity that creates or contributes to the creation
+of Modifications.
+
+1.2 "Contributor Version" means the combination of the Original Code, prior
+Modifications used by a Contributor, and the Modifications made by that particular
+Contributor.
+
+1.3 "Covered Code" means the Original Code or Modifications or the combination of
+the Original Code and Modifications, in each case including portions thereof.
+
+1.4 "Electronic Distribution Mechanism" means a mechanism generally accepted in
+the software development community for the electronic transfer of data.
+
+1.5 "Executable" means Covered Code in any form other than Source Code.
+
+1.6 "Initial Developer" means the individual or entity identified as the Initial
+Developer in the Source Code notice required by Exhibit A.
+
+1.7 "Larger Work" means a work which combines Covered Code or portions thereof with
+code not governed by the terms of this License.
+
+1.8 "License" means this document.
+
+1.8.1 "Licensable" means having the right to grant, to the maximum extent possible,
+whether at the time of the initial grant or subsequently acquired, any and all of
+the rights conveyed herein.
+
+1.9 "Modifications" means any addition to or deletion from the substance or structure
+of either the Original Code or any previous Modifications. When Covered Code is
+released as a series of files, a Modification is:
+
+A. Any addition to or deletion from the contents of a file containing Original Code
+or previous Modifications.
+
+B. Any new file that contains any part of the Original Code or previous Modifications.
+
+1.10 "Original Code" means Source Code of computer software code which is described in
+the Source Code notice required by Exhibit A as Original Code, and which, at the time
+of its release under this License is not already Covered Code governed by this License.
+
+1.10.1 "Patent Claims" means any patent claim(s), now owned or hereafter acquired,
+including without limitation, method, process, and apparatus claims, in any patent
+Licensable by grantor.
+
+1.11 "Source Code" means the preferred form of the Covered Code for making modifications
+to it, including all modules it contains, plus any associated interface definition files,
+scripts used to control compilation and installation of an Executable, or source code
+differential comparisons against either the Original Code or another well known,
+available Covered Code of the Contributor’s choice. The Source Code can be in a compressed
+or archival form, provided the appropriate decompression or de-archiving software is
+widely available for no charge.
+
+1.12 "You" (or "Your") means an individual or a legal entity exercising rights under, and
+complying with all of the terms of, this License or a future version of this License
+issued under Section 6.1. For legal entities, "You" includes any entity which controls,
+is controlled by, or is under common control with You. For purposes of this definition,
+"control" means (a) the power, direct or indirect, to cause the direction or management
+of such entity, whether by contract or otherwise, or (b) ownership of more than fifty
+percent (50%) of the outstanding shares or beneficial ownership of such entity.
+
+2. Source Code License.
+
+2.1 The Initial Developer Grant.
+
+The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive
+license, subject to third party intellectual property claims:
+
+(a) under intellectual property rights (other than patent or trademark) Licensable by
+Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute
+the Original Code (or portions thereof) with or without Modifications, and/or as part
+of a Larger Work; and
+
+(b) under Patents Claims infringed by the making, using or selling of Original Code, to
+make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of
+the Original Code (or portions thereof).
+
+(c) the licenses granted in this Section 2.1(a) and (b) are effective on the date
+Initial Developer first distributes Original Code under the terms of this License.
+
+(d) Notwithstanding Section 2.1(b) above, no patent license is granted: 1) for code
+that You delete from the Original Code; 2) separate from the Original Code; or 3) for
+infringements caused by: i) the modification of the Original Code or ii) the combination
+of the Original Code with other software or devices.
+
+2.2 Contributor Grant.
+
+Subject to third party intellectual property claims, each Contributor hereby grants You
+a world-wide, royalty-free, non-exclusive license
+
+(a) under intellectual property rights (other than patent or trademark) Licensable by
+Contributor, to use, reproduce, modify, display, perform, sublicense and distribute
+the Modifications created by such Contributor (or portions thereof) either on an
+unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger
+Work; and
+
+(b) under Patent Claims infringed by the making, using, or selling of Modifications
+made by that Contributor either alone and/or in combination with its Contributor
+Version (or portions of such combination), to make, use, sell, offer for sale, have
+made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or
+portions thereof); and 2) the combination of Modifications made by that Contributor
+with its Contributor Version (or portions of such combination).
+
+(c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date
+Contributor first makes Commercial Use of the Covered Code.
+
+(d) Notwithstanding Section 2.2(b) above, no patent license is granted: 1) for any code
+that Contributor has deleted from the Contributor Version; 2) separate from the
+Contributor Version; 3) for infringements caused by: i) third party modifications of
+Contributor Version or ii) the combination of Modifications made by that Contributor
+with other software (except as part of the Contributor Version) or other devices; or
+4) under Patent Claims infringed by Covered Code in the absence of Modifications made
+by that Contributor.
+
+3. Distribution Obligations.
+
+3.1 Application of License.
+
+The Modifications which You create or to which You contribute are governed by the terms
+of this License, including without limitation Section 2.2. The Source Code version of
+Covered Code may be distributed only under the terms of this License or a future version
+of this License released under Section 6.1, and You must include a copy of this License
+with every copy of the Source Code You distribute. You may not offer or impose any terms
+on any Source Code version that alters or restricts the applicable version of this License
+or the recipients’ rights hereunder. However, You may include an additional document
+offering the additional rights described in Section 3.5.
+
+3.2 Availability of Source Code.
+
+Any Modification which You create or to which You contribute must be made available in
+Source Code form under the terms of this License either on the same media as an Executable
+version or via an accepted Electronic Distribution Mechanism to anyone to whom you made
+an Executable version available; and if made available via Electronic Distribution
+Mechanism, must remain available for at least twelve (12) months after the date it
+initially became available, or at least six (6) months after a subsequent version of that
+particular Modification has been made available to such recipients. You are responsible
+for ensuring that the Source Code version remains available even if the Electronic
+Distribution Mechanism is maintained by a third party.
+
+3.3 Description of Modifications.
+
+You must cause all Covered Code to which You contribute to contain a file documenting the
+changes You made to create that Covered Code and the date of any change. You must include
+a prominent statement that the Modification is derived, directly or indirectly, from
+Original Code provided by the Initial Developer and including the name of the Initial
+Developer in (a) the Source Code, and (b) in any notice in an Executable version or
+related documentation in which You describe the origin or ownership of the Covered Code.
+
+3.4 Intellectual Property Matters
+
+(a) Third Party Claims.
+
+If Contributor has knowledge that a license under a third party’s intellectual property
+rights is required to exercise the rights granted by such Contributor under Sections 2.1
+or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL"
+which describes the claim and the party making the claim in sufficient detail that a
+recipient will know whom to contact. If Contributor obtains such knowledge after the
+Modification is made available as described in Section 3.2, Contributor shall promptly
+modify the LEGAL file in all copies Contributor makes available thereafter and shall take
+other steps (such as notifying appropriate mailing lists or newsgroups) reasonably
+calculated to inform those who received the Covered Code that new knowledge has been obtained.
+
+(b) Contributor APIs.
+
+If Contributor’s Modifications include an application programming interface and Contributor
+has knowledge of patent licenses which are reasonably necessary to implement that API,
+Contributor must also include this information in the LEGAL file.
+
+(c) Representations.
+
+Contributor represents that, except as disclosed pursuant to Section 3.4(a) above, Contributor
+believes that Contributor’s Modifications are Contributor’s original creation(s) and/or
+Contributor has sufficient rights to grant the rights conveyed by this License.
+
+3.5 Required Notices.
+
+You must duplicate the notice in Exhibit A in each file of the Source Code. If it is not
+possible to put such notice in a particular Source Code file due to its structure, then
+You must include such notice in a location (such as a relevant directory) where a user
+would be likely to look for such a notice. If You created one or more Modification(s)
+You may add your name as a Contributor to the notice described in Exhibit A. You must
+also duplicate this License in any documentation for the Source Code where You describe
+recipients’ rights or ownership rights relating to Covered Code. You may choose to offer,
+and to charge a fee for, warranty, support, indemnity or liability obligations to one or
+more recipients of Covered Code. However, You may do so only on Your own behalf, and not
+on behalf of the Initial Developer or any Contributor. You must make it absolutely clear
+than any such warranty, support, indemnity or liability obligation is offered by You alone,
+and You hereby agree to indemnify the Initial Developer and every Contributor for any
+liability incurred by the Initial Developer or such Contributor as a result of warranty,
+support, indemnity or liability terms You offer.
+
+3.6 Distribution of Executable Versions.
+
+You may distribute Covered Code in Executable form only if the requirements of Section
+3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the
+Source Code version of the Covered Code is available under the terms of this License,
+including a description of how and where You have fulfilled the obligations of Section
+3.2. The notice must be conspicuously included in any notice in an Executable version,
+related documentation or collateral in which You describe recipients’ rights relating to
+the Covered Code. You may distribute the Executable version of Covered Code or ownership
+rights under a license of Your choice, which may contain terms different from this License,
+provided that You are in compliance with the terms of this License and that the license for
+the Executable version does not attempt to limit or alter the recipient’s rights in the
+Source Code version from the rights set forth in this License. If You distribute the
+Executable version under a different license You must make it absolutely clear that any
+terms which differ from this License are offered by You alone, not by the Initial Developer,
+Original Developer or any Contributor. You hereby agree to indemnify the Initial Developer,
+Original Developer and every Contributor for any liability incurred by the Initial Developer,
+Original Developer or such Contributor as a result of any such terms You offer.
+
+3.7 Larger Works.
+
+You may create a Larger Work by combining Covered Code with other code not governed by the
+terms of this License and distribute the Larger Work as a single product. In such a case, You
+must make sure the requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+If it is impossible for You to comply with any of the terms of this License with respect to
+some or all of the Covered Code due to statute, judicial order, or regulation then You must:
+(a) comply with the terms of this License to the maximum extent possible; and (b) describe the
+limitations and the code they affect. Such description must be included in the LEGAL file
+described in Section 3.4 and must be included with all distributions of the Source Code.
+Except to the extent prohibited by statute or regulation, such description must be
+sufficiently detailed for a recipient of ordinary skill to be able to understand it.
+
+5. Application of this License.
+
+This License applies to code to which the Initial Developer has attached the notice in Exhibit
+A and to related Covered Code.
+
+6. Versions of the License.
+
+6.1 New Versions.
+
+Socialtext, Inc. ("Socialtext") may publish revised and/or new versions of the License from
+time to time. Each version will be given a distinguishing version number.
+
+6.2 Effect of New Versions.
+
+Once Covered Code has been published under a particular version of the License, You may always
+continue to use it under the terms of that version. You may also choose to use such Covered
+Code under the terms of any subsequent version of the License published by Socialtext. No one
+other than Socialtext has the right to modify the terms applicable to Covered Code created
+under this License.
+
+6.3 Derivative Works.
+
+If You create or use a modified version of this License (which you may only do in order to
+apply it to code which is not already Covered Code governed by this License), You must (a)
+rename Your license so that the phrases "Socialtext", "CPAL" or any confusingly similar phrase
+do not appear in your license (except to note that your license differs from this License) and
+(b) otherwise make it clear that Your version of the license contains terms which differ from
+the CPAL. (Filling in the name of the Initial Developer, Original Developer, Original Code or
+Contributor in the notice described in Exhibit A shall not of themselves be deemed to be
+modifications of this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND,
+EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS
+FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK
+AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE
+DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER, ORIGINAL DEVELOPER OR ANY OTHER
+CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS
+AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+8.1 This License and the rights granted hereunder will terminate automatically if You fail to
+comply with terms herein and fail to cure such breach within 30 days of becoming aware of the
+breach. All sublicenses to the Covered Code which are properly granted shall survive any
+termination of this License. Provisions which, by their nature, must remain in effect beyond
+the termination of this License shall survive.
+
+8.2 If You initiate litigation by asserting a patent infringement claim (excluding declatory
+judgment actions) against Initial Developer, Original Developer or a Contributor (the Initial
+Developer, Original Developer or Contributor against whom You file such action is referred to
+as "Participant") alleging that:
+
+(a) such Participant’s Contributor Version directly or indirectly infringes any patent, then
+any and all rights granted by such Participant to You under Sections 2.1 and/or 2.2 of this
+License shall, upon 60 days notice from Participant terminate prospectively, unless if within
+60 days after receipt of notice You either: (i) agree in writing to pay Participant a mutually
+agreeable reasonable royalty for Your past and future use of Modifications made by such
+Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version
+against such Participant. If within 60 days of notice, a reasonable royalty and payment
+arrangement are not mutually agreed upon in writing by the parties or the litigation claim is
+not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2
+automatically terminate at the expiration of the 60 day notice period specified above.
+
+(b) any software, hardware, or device, other than such Participant’s Contributor Version,
+directly or indirectly infringes any patent, then any rights granted to You by such Participant
+under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used,
+sold, distributed, or had made, Modifications made by that Participant.
+
+8.3 If You assert a patent infringement claim against Participant alleging that such
+Participant’s Contributor Version directly or indirectly infringes any patent where such claim
+is resolved (such as by license or settlement) prior to the initiation of patent infringement
+litigation, then the reasonable value of the licenses granted by such Participant under Sections
+2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or
+license.
+
+8.4 In the event of termination under Sections 8.1 or 8.2 above, all end user license agreements
+(excluding distributors and resellers) which have been validly granted by You or any distributor
+hereunder prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT,
+OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ORIGINAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR
+ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON
+FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING,
+WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION,
+OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF
+THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR
+DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY’S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+The Covered Code is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995),
+consisting of "commercial computer software" and "commercial computer software documentation," as
+such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48
+C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered
+Code with only those rights set forth herein.
+
+11. MISCELLANEOUS.
+
+This License represents the complete agreement concerning subject matter hereof. If any provision
+of this License is held to be unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. This License shall be governed by California law provisions
+(except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law
+provisions. With respect to disputes in which at least one party is a citizen of, or an entity
+chartered or registered to do business in the United States of America, any litigation relating to
+this License shall be subject to the jurisdiction of the Federal Courts of the Northern District
+of California, with venue lying in Santa Clara County, California, with the losing party
+responsible for costs, including without limitation, court costs and reasonable attorneys’ fees
+and expenses. The application of the United Nations Convention on Contracts for the International
+Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a
+contract shall be construed against the drafter shall not apply to this License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+As between Initial Developer, Original Developer and the Contributors, each party is responsible
+for claims and damages arising, directly or indirectly, out of its utilization of rights under
+this License and You agree to work with Initial Developer, Original Developer and Contributors to
+distribute such responsibility on an equitable basis. Nothing herein is intended or shall be
+deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+Initial Developer may designate portions of the Covered Code as Multiple-Licensed.
+Multiple-Licensed means that the Initial Developer permits you to utilize portions of the Covered
+Code under Your choice of the CPAL or the alternative licenses, if any, specified by the Initial
+Developer in the file described in Exhibit A.
+
+14. ADDITIONAL TERM: ATTRIBUTION
+
+(a) As a modest attribution to the organizer of the development of the Original Code ("Original
+Developer"), in the hope that its promotional value may help justify the time, money and effort
+invested in writing the Original Code, the Original Developer may include in Exhibit B
+("Attribution Information") a requirement that each time an Executable and Source Code or a Larger
+Work is launched or initially run (which includes initiating a session), a prominent display of
+the Original Developer’s Attribution Information (as defined below) must occur on the graphic user
+interface employed by the end user to access such Covered Code (which may include display on a
+splash screen), if any. The size of the graphic image should be consistent with the size of the
+other elements of the Attribution Information. If the access by the end user to the Executable and
+Source Code does not create a graphic user interface for access to the Covered Code, this
+obligation shall not apply. If the Original Code displays such Attribution Information in a
+particular form (such as in the form of a splash screen, notice at login, an "about" display, or
+dedicated attribution area on user interface screens), continued use of such form for that
+Attribution Information is one way of meeting this requirement for notice.
+
+(b) Attribution information may only include a copyright notice, a brief phrase, graphic image and
+a URL ("Attribution Information") and is subject to the Attribution Limits as defined below. For
+these purposes, prominent shall mean display for sufficient duration to give reasonable notice to
+the user of the identity of the Original Developer and that if You include Attribution Information
+or similar information for other parties, You must ensure that the Attribution Information for the
+Original Developer shall be no less prominent than such Attribution Information or similar
+information for the other party. For greater certainty, the Original Developer may choose to
+specify in Exhibit B below that the above attribution requirement only applies to an Executable
+and Source Code resulting from the Original Code or any Modification, but not a Larger Work. The
+intent is to provide for reasonably modest attribution, therefore the Original Developer cannot
+require that You display, at any time, more than the following information as Attribution
+Information: (a) a copyright notice including the name of the Original Developer; (b) a word or
+one phrase (not exceeding 10 words); (c) one graphic image provided by the Original Developer; and
+(d) a URL (collectively, the "Attribution Limits").
+
+(c) If Exhibit B does not include any Attribution Information, then there are no requirements for
+You to display any Attribution Information of the Original Developer.
+
+(d) You acknowledge that all trademarks, service marks and/or trade names contained within the
+Attribution Information distributed with the Covered Code are the exclusive property of their
+owners and may only be used with the permission of their owners, or under circumstances otherwise
+permitted by law or as expressly set out in this License.
+
+15. ADDITIONAL TERM: NETWORK USE.
+The term "External Deployment" means the use, distribution, or communication of the Original Code
+or Modifications in any way such that the Original Code or Modifications may be used by anyone
+other than You, whether those works are distributed or communicated to those persons or made
+available as an application intended for use over a network. As an express condition for the grants
+of license hereunder, You must treat any External Deployment by You of the Original Code or
+Modifications as a distribution under section 3.1 and make Source Code available under Section 3.2.
+
+EXHIBIT A. Common Public Attribution License Version 1.0.
+
+"The contents of this file are subject to the Common Public Attribution License Version 1.0 (the
+"License"); you may not use this file except in compliance with the License. You may obtain a copy
+of the License at _____________. The License is based on the Mozilla Public License Version 1.1 but
+Sections 14 and 15 have been added to cover use of software over a computer network and provide for
+limited attribution for the Original Developer. In addition, Exhibit A has been modified to be
+consistent with Exhibit B.
+
+Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+KIND, either express or implied. See the License for the specific language governing rights and
+limitations under the License.
+
+The Original Code is______________________.
+
+The Original Developer is not the Initial Developer and is __________. If left blank, the Original
+Developer is the Initial Developer.
+
+The Initial Developer of the Original Code is ____________. All portions of the code written by
+___________ are Copyright (c) _____. All Rights Reserved.
+
+Contributor ______________________.
+
+Alternatively, the contents of this file may be used under the terms of the _____ license (the
+[___] License), in which case the provisions of [______] License are applicable instead of those
+above.
+
+If you wish to allow use of your version of this file only under the terms of the [____] License
+and not to allow others to use your version of this file under the CPAL, indicate your decision by
+deleting the provisions above and replace them with the notice and other provisions required by
+the [___] License. If you do not delete the provisions above, a recipient may use your version of
+this file under either the CPAL or the [___] License."
+
+[NOTE: The text of this Exhibit A may differ slightly from the text of the notices in the Source
+Code files of the Original Code. You should use the text of this Exhibit A rather than the text
+found in the Original Code Source Code for Your Modifications.]
+
+EXHIBIT B. Attribution Information
+
+When the TableEditor is producing and/or controlling the display the Graphic Image must be
+displayed on the screen visible to the user in a manner comparable to that in the
+Original Code. The Attribution Phrase must be displayed as a "tooltip" or "hover-text" for
+that image. The image must be linked to the Attribution URL so as to access that page
+when clicked. If the user interface includes a prominent "about" display which includes
+factual prominent attribution in a form similar to that in the "about" display included
+with the Original Code, including Socialtext copyright notices and URLs, then the image
+need not be linked to the Attribution URL but the "tool-tip" is still required.
+
+Attribution Copyright Notice:
+
+ Copyright (C) 2009 Socialtext, Inc.
+ All Rights Reserved.
+
+Attribution Phrase (not exceeding 10 words): SocialCalc
+
+Attribution URL: http://www.socialcalc.org
+
+Graphic Image: The contents of the sc-logo.gif file in the Original Code or
+a suitable replacement from http://www.socialcalc.org/licenses specified as
+being for SocialCalc.
+
+Display of Attribution Information is required in Larger Works which are defined
+in the CPAL as a work which combines Covered Code or portions thereof with code
+not governed by the terms of the CPAL.
+
+
+=========================================
+ THE ARTISTIC LICENSE 2.0
+=========================================
+
+ The Artistic License 2.0
+
+ Copyright (c) 2000-2006, The Perl Foundation.
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+Preamble
+
+This license establishes the terms under which a given free software
+Package may be copied, modified, distributed, and/or redistributed.
+The intent is that the Copyright Holder maintains some artistic
+control over the development of that Package while still keeping the
+Package available as open source and free software.
+
+You are always permitted to make arrangements wholly outside of this
+license directly with the Copyright Holder of a given Package. If the
+terms of this license do not permit the full use that you propose to
+make of the Package, you should contact the Copyright Holder and seek
+a different licensing arrangement.
+
+Definitions
+
+ "Copyright Holder" means the individual(s) or organization(s)
+ named in the copyright notice for the entire Package.
+
+ "Contributor" means any party that has contributed code or other
+ material to the Package, in accordance with the Copyright Holder's
+ procedures.
+
+ "You" and "your" means any person who would like to copy,
+ distribute, or modify the Package.
+
+ "Package" means the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection and/or of
+ those files. A given Package may consist of either the Standard
+ Version, or a Modified Version.
+
+ "Distribute" means providing a copy of the Package or making it
+ accessible to anyone else, or in the case of a company or
+ organization, to others outside of your company or organization.
+
+ "Distributor Fee" means any fee that you charge for Distributing
+ this Package or providing support for this Package to another
+ party. It does not mean licensing fees.
+
+ "Standard Version" refers to the Package if it has not been
+ modified, or has been modified only in ways explicitly requested
+ by the Copyright Holder.
+
+ "Modified Version" means the Package, if it has been changed, and
+ such changes were not explicitly requested by the Copyright
+ Holder.
+
+ "Original License" means this Artistic License as Distributed with
+ the Standard Version of the Package, in its current version or as
+ it may be modified by The Perl Foundation in the future.
+
+ "Source" form means the source code, documentation source, and
+ configuration files for the Package.
+
+ "Compiled" form means the compiled bytecode, object code, binary,
+ or any other form resulting from mechanical transformation or
+ translation of the Source form.
+
+
+Permission for Use and Modification Without Distribution
+
+(1) You are permitted to use the Standard Version and create and use
+Modified Versions for any purpose without restriction, provided that
+you do not Distribute the Modified Version.
+
+
+Permissions for Redistribution of the Standard Version
+
+(2) You may Distribute verbatim copies of the Source form of the
+Standard Version of this Package in any medium without restriction,
+either gratis or for a Distributor Fee, provided that you duplicate
+all of the original copyright notices and associated disclaimers. At
+your discretion, such verbatim copies may or may not include a
+Compiled form of the Package.
+
+(3) You may apply any bug fixes, portability changes, and other
+modifications made available from the Copyright Holder. The resulting
+Package will still be considered the Standard Version, and as such
+will be subject to the Original License.
+
+
+Distribution of Modified Versions of the Package as Source
+
+(4) You may Distribute your Modified Version as Source (either gratis
+or for a Distributor Fee, and with or without a Compiled form of the
+Modified Version) provided that you clearly document how it differs
+from the Standard Version, including, but not limited to, documenting
+any non-standard features, executables, or modules, and provided that
+you do at least ONE of the following:
+
+ (a) make the Modified Version available to the Copyright Holder
+ of the Standard Version, under the Original License, so that the
+ Copyright Holder may include your modifications in the Standard
+ Version.
+
+ (b) ensure that installation of your Modified Version does not
+ prevent the user installing or running the Standard Version. In
+ addition, the Modified Version must bear a name that is different
+ from the name of the Standard Version.
+
+ (c) allow anyone who receives a copy of the Modified Version to
+ make the Source form of the Modified Version available to others
+ under
+
+ (i) the Original License or
+
+ (ii) a license that permits the licensee to freely copy,
+ modify and redistribute the Modified Version using the same
+ licensing terms that apply to the copy that the licensee
+ received, and requires that the Source form of the Modified
+ Version, and of any works derived from it, be made freely
+ available in that license fees are prohibited but Distributor
+ Fees are allowed.
+
+
+Distribution of Compiled Forms of the Standard Version
+or Modified Versions without the Source
+
+(5) You may Distribute Compiled forms of the Standard Version without
+the Source, provided that you include complete instructions on how to
+get the Source of the Standard Version. Such instructions must be
+valid at the time of your distribution. If these instructions, at any
+time while you are carrying out such distribution, become invalid, you
+must provide new instructions on demand or cease further distribution.
+If you provide valid instructions or cease distribution within thirty
+days after you become aware that the instructions are invalid, then
+you do not forfeit any of your rights under this license.
+
+(6) You may Distribute a Modified Version in Compiled form without
+the Source, provided that you comply with Section 4 with respect to
+the Source of the Modified Version.
+
+
+Aggregating or Linking the Package
+
+(7) You may aggregate the Package (either the Standard Version or
+Modified Version) with other packages and Distribute the resulting
+aggregation provided that you do not charge a licensing fee for the
+Package. Distributor Fees are permitted, and licensing fees for other
+components in the aggregation are permitted. The terms of this license
+apply to the use and Distribution of the Standard or Modified Versions
+as included in the aggregation.
+
+(8) You are permitted to link Modified and Standard Versions with
+other works, to embed the Package in a larger work of your own, or to
+build stand-alone binary or bytecode versions of applications that
+include the Package, and Distribute the result without restriction,
+provided the result does not expose a direct interface to the Package.
+
+
+Items That are Not Considered Part of a Modified Version
+
+(9) Works (including, but not limited to, modules and scripts) that
+merely extend or make use of the Package, do not, by themselves, cause
+the Package to be a Modified Version. In addition, such works are not
+considered parts of the Package itself, and are not subject to the
+terms of this license.
+
+
+General Provisions
+
+(10) Any use, modification, and distribution of the Standard or
+Modified Versions is governed by this Artistic License. By using,
+modifying or distributing the Package, you accept this license. Do not
+use, modify, or distribute the Package, if you do not accept this
+license.
+
+(11) If your Modified Version has been derived from a Modified
+Version made by someone other than you, you are nevertheless required
+to ensure that your Modified Version complies with the requirements of
+this license.
+
+(12) This license does not grant you the right to use any trademark,
+service mark, tradename, or logo of the Copyright Holder.
+
+(13) This license includes the non-exclusive, worldwide,
+free-of-charge patent license to make, have made, use, offer to sell,
+sell, import and otherwise transfer the Package with respect to any
+patent claims licensable by the Copyright Holder that are necessarily
+infringed by the Package. If you institute patent litigation
+(including a cross-claim or counterclaim) against any party alleging
+that the Package constitutes direct or contributory patent
+infringement, then this Artistic License to you shall terminate on the
+date that such litigation is filed.
+
+(14) Disclaimer of Warranty:
+THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
+IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
+LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+[End of LICENSE.txt]
+
+
32 README
@@ -0,0 +1,32 @@
+ -=[MeetingCalc]=-
+
+ Language: CoffeeScript
+ Runtime: Node.js
+ Services: Redis
+ Browsers currently tested: Safari & Firefox.
+
+ .oO( Setup Instructions )Oo.
+
+ $ stackato push meetingcalc
+ Would you like to deploy from the current directory ? [Yn]:
+ Application Deployed URL: 'meetingcalc.stackato.local'?
+ Detected a Node.js Application, is this correct ? [Yn]:
+ Memory Reservation ? (64M, 128M, 256M, 512M, 1G, or 2G):
+ Would you like to bind any services to 'meetingcalc' ? [yN]: y
+ The following system services are available
+ 1. mongodb
+ 2. mysql
+ 3. postgresql
+ 4. redis
+ 5. <None of the above>
+ Please select one you wish to provision: 4
+ Specify the name of the service [redis-dd80a]:
+ Creating Service: OK
+ Binding Service: OK
+ Uploading Application:
+ Checking for available resources: OK
+ Processing resources: OK
+ Packing application: OK
+ Uploading (12K): 98% OK
+ Push Status: OK
+ Staging Application: OK
189 app.coffee
@@ -0,0 +1,189 @@
+port = Number(process.env.VCAP_APP_PORT || 3000)
+host = process.env.VCAP_APP_HOST || '127.0.0.1'
+redisPort = null
+redisHost = null
+redisPass = null
+
+services = JSON.parse(process.env.VCAP_SERVICES || "{}")
+for name, items of services
+ continue unless /^redis/.test(name)
+ if items && items.length
+ redisPort = items[0].credentials.port
+ redisHost = items[0].credentials.hostname
+ redisPass = items[0].credentials.password
+
+db = require('redis').createClient(redisPort, redisHost)
+db.auth(redisPass) if redisPass
+
+require('zappa') port, host, {db}, ->
+ enable 'serve jquery'
+ app.use express.static __dirname
+
+ def {db}
+
+ get '/': ->
+ response.contentType 'text/html'
+ response.sendfile 'index.mt'
+
+ get '/edit': ->
+ response.contentType 'text/html'
+ response.sendfile 'index.mt'
+
+ get '/start': -> render 'start'
+ get '/new': ->
+ response.redirect require("uuid-pure").newId(10)
+
+ view room: ->
+ coffeescript ->
+ window.location = '/#' + window.location.pathname.replace(/.*\//, '')
+
+ view start: ->
+ div id:"topnav_wrap", -> div id:"navigation"
+ div id:"intro-left", ->
+ h1 "MeetingCalc"
+ h2 "MeetingCalc is a web spreadsheet."
+ p "Your data is saved on the web, and people can edit the same document at the same time. Everybody's changes are instantly reflected on all screens."
+ p "Work together on inventories, survey forms, list managements, brainstorming sessions and more!"
+ div id:"intro-links", ->
+ a id:"newpadbutton", href:"/new", ->
+ span "Create new pad"
+ small "No sign-up, start editing instantly"
+
+ view layout: ->
+ html ->
+ head ->
+ title "MeetingCalc"
+ link href:"/start.css", rel:"stylesheet", type:"text/css"
+ body id:"framedpagebody", class:"home", ->
+ div id:"top", -> @body
+
+ at broadcast: ->
+ #io.sockets.in(@room).emit 'broadcast', @
+ switch @type
+ when 'chat'
+ db.rpush "chat-#{@room}", @msg, =>
+ io.sockets.emit 'chat', @
+ return
+ when 'ask.ecells'
+ db.hgetall "ecell-#{@room}", (err, values) =>
+ io.sockets.emit 'broadcast',
+ type: 'ecells'
+ ecells: values
+ room: @room
+ return
+ when 'my.ecell'
+ db.hset "ecell-#{@room}", @user, @ecell
+ return
+ when 'execute'
+ db.rpush "log-#{@room}", @cmdstr, =>
+ io.sockets.emit 'broadcast', @
+ return
+ when 'ask.snapshot'
+ db.lrange "log-#{@room}", 0, -1, (err, log) =>
+ db.lrange "chat-#{@room}", 0, -1, (err, chat) =>
+ io.sockets.emit 'broadcast',
+ type: 'log'
+ to: @user
+ room: @room
+ log: log
+ chat: chat
+ return
+ io.sockets.emit 'broadcast', @
+
+ client '/player.js': ->
+ SocialCalc ?= {}
+ SocialCalc._username = Math.random().toString()
+ SocialCalc.isConnected = true
+ SocialCalc.hadSnapshot = false
+ SocialCalc._room = window.location.hash.replace('#', '')
+ unless SocialCalc._room
+ window.location = '/start'
+ return
+
+ connect()
+ #subscribe(SocialCalc._room)
+
+ SocialCalc.Callbacks.broadcast = (type, data={}) ->
+ return unless SocialCalc.isConnected
+ data.user = SocialCalc._username
+ data.room = SocialCalc._room
+ data.type = type
+ emit 'broadcast', data
+
+ SocialCalc.isConnected = true
+ SocialCalc.Callbacks.broadcast "ask.snapshot"
+
+ at broadcast: ->
+ return unless SocialCalc?.isConnected
+ return if @user == SocialCalc._username
+ return if @to and @to != SocialCalc._username
+ return if @room and @room != SocialCalc._room
+
+ editor = SocialCalc.CurrentSpreadsheetControlObject.editor
+ switch @type
+ when "chat"
+ window.addmsg @msg
+ when "ecells"
+ for user, ecell of @ecells
+ continue if user == SocialCalc._username
+ peerClass = " " + user + " defaultPeer"
+ find = new RegExp(peerClass, "g")
+ cr = SocialCalc.coordToCr(ecell)
+ cell = SocialCalc.GetEditorCellElement(editor, cr.row, cr.col)
+ cell.element.className += peerClass if cell.element.className.search(find) == -1
+ break
+ when "ecell"
+ peerClass = " " + @user + " defaultPeer"
+ find = new RegExp(peerClass, "g")
+ if @original
+ origCR = SocialCalc.coordToCr(@original)
+ origCell = SocialCalc.GetEditorCellElement(editor, origCR.row, origCR.col)
+ origCell.element.className = origCell.element.className.replace(find, "")
+ cr = SocialCalc.coordToCr(@ecell)
+ cell = SocialCalc.GetEditorCellElement(editor, cr.row, cr.col)
+ cell.element.className += peerClass if cell.element.className.search(find) == -1
+ when "ask.snapshot"
+ SocialCalc.Callbacks.broadcast "snapshot",
+ to: @user
+ snapshot: SocialCalc.CurrentSpreadsheetControlObject.CreateSpreadsheetSave()
+ when "ask.ecell"
+ SocialCalc.Callbacks.broadcast "ecell",
+ to: @user
+ ecell: editor.ecell.coord
+ break
+ when "log"
+ break if SocialCalc.hadSnapshot
+ SocialCalc.hadSnapshot = true
+ spreadsheet = SocialCalc.CurrentSpreadsheetControlObject
+ window.addmsg @chat.join("\n"), true
+ cmdstr = @log.join("\n")
+ SocialCalc.CurrentSpreadsheetControlObject.context.sheetobj.ScheduleSheetCommands cmdstr, false, true
+ editor = SocialCalc.CurrentSpreadsheetControlObject.editor
+# editor.MoveECellCallback.broadcast = (e) ->
+# SocialCalc.Callbacks.broadcast "my.ecell"
+# ecell: e.ecell.coord
+ when "snapshot"
+ break if SocialCalc.hadSnapshot
+ SocialCalc.hadSnapshot = true
+ spreadsheet = SocialCalc.CurrentSpreadsheetControlObject
+ parts = spreadsheet.DecodeSpreadsheetSave(@snapshot)
+ if parts
+ if parts.sheet
+ spreadsheet.sheet.ResetSheet()
+ spreadsheet.ParseSheetSave @snapshot.substring(parts.sheet.start, parts.sheet.end)
+ spreadsheet.editor.LoadEditorSettings @snapshot.substring(parts.edit.start, parts.edit.end) if parts.edit
+ if spreadsheet.editor.context.sheetobj.attribs.recalc == "off"
+ spreadsheet.ExecuteCommand "redisplay", ""
+ spreadsheet.ExecuteCommand "set sheet defaulttextvalueformat text-wiki"
+ else
+ spreadsheet.ExecuteCommand "recalc", ""
+ spreadsheet.ExecuteCommand "set sheet defaulttextvalueformat text-wiki"
+ break
+ when "execute"
+ SocialCalc.CurrentSpreadsheetControlObject.context.sheetobj.ScheduleSheetCommands @cmdstr, @saveundo, true
+ break
+
+ get '/:room': ->
+ @layout = no
+ render 'room', @
+
295 app.js
@@ -0,0 +1,295 @@
+(function() {
+ var db, host, items, name, port, redisHost, redisPass, redisPort, services;
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
+ port = Number(process.env.VCAP_APP_PORT || 3000);
+ host = process.env.VCAP_APP_HOST || '127.0.0.1';
+ redisPort = null;
+ redisHost = null;
+ redisPass = null;
+ services = JSON.parse(process.env.VCAP_SERVICES || "{}");
+ for (name in services) {
+ items = services[name];
+ if (!/^redis/.test(name)) {
+ continue;
+ }
+ if (items && items.length) {
+ redisPort = items[0].credentials.port;
+ redisHost = items[0].credentials.hostname;
+ redisPass = items[0].credentials.password;
+ }
+ }
+ db = require('redis').createClient(redisPort, redisHost);
+ if (redisPass) {
+ db.auth(redisPass);
+ }
+ require('zappa')(port, host, {
+ db: db
+ }, function() {
+ enable('serve jquery');
+ app.use(express.static(__dirname));
+ def({
+ db: db
+ });
+ get({
+ '/': function() {
+ response.contentType('text/html');
+ return response.sendfile('index.mt');
+ }
+ });
+ get({
+ '/edit': function() {
+ response.contentType('text/html');
+ return response.sendfile('index.mt');
+ }
+ });
+ get({
+ '/start': function() {
+ return render('start');
+ }
+ });
+ get({
+ '/new': function() {
+ return response.redirect(require("uuid-pure").newId(10));
+ }
+ });
+ view({
+ room: function() {
+ return coffeescript(function() {
+ return window.location = '/#' + window.location.pathname.replace(/.*\//, '');
+ });
+ }
+ });
+ view({
+ start: function() {
+ div({
+ id: "topnav_wrap"
+ }, function() {
+ return div({
+ id: "navigation"
+ });
+ });
+ return div({
+ id: "intro-left"
+ }, function() {
+ h1("MeetingCalc");
+ h2("MeetingCalc is a web spreadsheet.");
+ p("Your data is saved on the web, and people can edit the same document at the same time. Everybody's changes are instantly reflected on all screens.");
+ p("Work together on inventories, survey forms, list managements, brainstorming sessions and more!");
+ return div({
+ id: "intro-links"
+ }, function() {
+ return a({
+ id: "newpadbutton",
+ href: "/new"
+ }, function() {
+ span("Create new pad");
+ return small("No sign-up, start editing instantly");
+ });
+ });
+ });
+ }
+ });
+ view({
+ layout: function() {
+ return html(function() {
+ head(function() {
+ title("MeetingCalc");
+ return link({
+ href: "/start.css",
+ rel: "stylesheet",
+ type: "text/css"
+ });
+ });
+ return body({
+ id: "framedpagebody",
+ "class": "home"
+ }, function() {
+ return div({
+ id: "top"
+ }, function() {
+ return this.body;
+ });
+ });
+ });
+ }
+ });
+ at({
+ broadcast: function() {
+ switch (this.type) {
+ case 'chat':
+ db.rpush("chat-" + this.room, this.msg, __bind(function() {
+ return io.sockets.emit('chat', this);
+ }, this));
+ return;
+ case 'ask.ecells':
+ db.hgetall("ecell-" + this.room, __bind(function(err, values) {
+ return io.sockets.emit('broadcast', {
+ type: 'ecells',
+ ecells: values,
+ room: this.room
+ });
+ }, this));
+ return;
+ case 'my.ecell':
+ db.hset("ecell-" + this.room, this.user, this.ecell);
+ return;
+ case 'execute':
+ db.rpush("log-" + this.room, this.cmdstr, __bind(function() {
+ return io.sockets.emit('broadcast', this);
+ }, this));
+ return;
+ case 'ask.snapshot':
+ db.lrange("log-" + this.room, 0, -1, __bind(function(err, log) {
+ return db.lrange("chat-" + this.room, 0, -1, __bind(function(err, chat) {
+ return io.sockets.emit('broadcast', {
+ type: 'log',
+ to: this.user,
+ room: this.room,
+ log: log,
+ chat: chat
+ });
+ }, this));
+ }, this));
+ return;
+ }
+ return io.sockets.emit('broadcast', this);
+ }
+ });
+ client({
+ '/player.js': function() {
+ if (typeof SocialCalc === "undefined" || SocialCalc === null) {
+ SocialCalc = {};
+ }
+ SocialCalc._username = Math.random().toString();
+ SocialCalc.isConnected = true;
+ SocialCalc.hadSnapshot = false;
+ SocialCalc._room = window.location.hash.replace('#', '');
+ if (!SocialCalc._room) {
+ window.location = '/start';
+ return;
+ }
+ connect();
+ SocialCalc.Callbacks.broadcast = function(type, data) {
+ if (data == null) {
+ data = {};
+ }
+ if (!SocialCalc.isConnected) {
+ return;
+ }
+ data.user = SocialCalc._username;
+ data.room = SocialCalc._room;
+ data.type = type;
+ return emit('broadcast', data);
+ };
+ SocialCalc.isConnected = true;
+ SocialCalc.Callbacks.broadcast("ask.snapshot");
+ return at({
+ broadcast: function() {
+ var cell, cmdstr, cr, ecell, editor, find, origCR, origCell, parts, peerClass, spreadsheet, user, _ref;
+ if (!(typeof SocialCalc !== "undefined" && SocialCalc !== null ? SocialCalc.isConnected : void 0)) {
+ return;
+ }
+ if (this.user === SocialCalc._username) {
+ return;
+ }
+ if (this.to && this.to !== SocialCalc._username) {
+ return;
+ }
+ if (this.room && this.room !== SocialCalc._room) {
+ return;
+ }
+ editor = SocialCalc.CurrentSpreadsheetControlObject.editor;
+ switch (this.type) {
+ case "chat":
+ return window.addmsg(this.msg);
+ case "ecells":
+ _ref = this.ecells;
+ for (user in _ref) {
+ ecell = _ref[user];
+ if (user === SocialCalc._username) {
+ continue;
+ }
+ peerClass = " " + user + " defaultPeer";
+ find = new RegExp(peerClass, "g");
+ cr = SocialCalc.coordToCr(ecell);
+ cell = SocialCalc.GetEditorCellElement(editor, cr.row, cr.col);
+ if (cell.element.className.search(find) === -1) {
+ cell.element.className += peerClass;
+ }
+ }
+ break;
+ case "ecell":
+ peerClass = " " + this.user + " defaultPeer";
+ find = new RegExp(peerClass, "g");
+ if (this.original) {
+ origCR = SocialCalc.coordToCr(this.original);
+ origCell = SocialCalc.GetEditorCellElement(editor, origCR.row, origCR.col);
+ origCell.element.className = origCell.element.className.replace(find, "");
+ }
+ cr = SocialCalc.coordToCr(this.ecell);
+ cell = SocialCalc.GetEditorCellElement(editor, cr.row, cr.col);
+ if (cell.element.className.search(find) === -1) {
+ return cell.element.className += peerClass;
+ }
+ break;
+ case "ask.snapshot":
+ return SocialCalc.Callbacks.broadcast("snapshot", {
+ to: this.user,
+ snapshot: SocialCalc.CurrentSpreadsheetControlObject.CreateSpreadsheetSave()
+ });
+ case "ask.ecell":
+ SocialCalc.Callbacks.broadcast("ecell", {
+ to: this.user,
+ ecell: editor.ecell.coord
+ });
+ break;
+ case "log":
+ if (SocialCalc.hadSnapshot) {
+ break;
+ }
+ SocialCalc.hadSnapshot = true;
+ spreadsheet = SocialCalc.CurrentSpreadsheetControlObject;
+ window.addmsg(this.chat.join("\n"), true);
+ cmdstr = this.log.join("\n");
+ SocialCalc.CurrentSpreadsheetControlObject.context.sheetobj.ScheduleSheetCommands(cmdstr, false, true);
+ return editor = SocialCalc.CurrentSpreadsheetControlObject.editor;
+ case "snapshot":
+ if (SocialCalc.hadSnapshot) {
+ break;
+ }
+ SocialCalc.hadSnapshot = true;
+ spreadsheet = SocialCalc.CurrentSpreadsheetControlObject;
+ parts = spreadsheet.DecodeSpreadsheetSave(this.snapshot);
+ if (parts) {
+ if (parts.sheet) {
+ spreadsheet.sheet.ResetSheet();
+ spreadsheet.ParseSheetSave(this.snapshot.substring(parts.sheet.start, parts.sheet.end));
+ }
+ if (parts.edit) {
+ spreadsheet.editor.LoadEditorSettings(this.snapshot.substring(parts.edit.start, parts.edit.end));
+ }
+ }
+ if (spreadsheet.editor.context.sheetobj.attribs.recalc === "off") {
+ spreadsheet.ExecuteCommand("redisplay", "");
+ spreadsheet.ExecuteCommand("set sheet defaulttextvalueformat text-wiki");
+ } else {
+ spreadsheet.ExecuteCommand("recalc", "");
+ spreadsheet.ExecuteCommand("set sheet defaulttextvalueformat text-wiki");
+ }
+ break;
+ case "execute":
+ SocialCalc.CurrentSpreadsheetControlObject.context.sheetobj.ScheduleSheetCommands(this.cmdstr, this.saveundo, true);
+ break;
+ }
+ }
+ });
+ }
+ });
+ return get({
+ '/:room': function() {
+ this.layout = false;
+ return render('room', this);
+ }
+ });
+ });
+}).call(this);
950 formatnumber2.js
@@ -0,0 +1,950 @@
+//
+/*
+// SocialCalc Number Formatting Library
+//
+// Part of the SocialCalc package.
+//
+// (c) Copyright 2008 Socialtext, Inc.
+// All Rights Reserved.
+//
+// The contents of this file are subject to the Artistic License 2.0; you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at http://socialcalc.org/licenses/al-20/.
+//
+// Some of the other files in the SocialCalc package are licensed under
+// different licenses. Please note the licenses of the modules you use.
+//
+// Code History:
+//
+// Initially coded by Dan Bricklin of Software Garden, Inc., for Socialtext, Inc.
+// Based in part on the SocialCalc 1.1.0 code written in Perl.
+// The SocialCalc 1.1.0 code was:
+// Portions (c) Copyright 2005, 2006, 2007 Software Garden, Inc.
+// All Rights Reserved.
+// Portions (c) Copyright 2007 Socialtext, Inc.
+// All Rights Reserved.
+// The Perl SocialCalc started as modifications to the wikiCalc(R) program, version 1.0.
+// wikiCalc 1.0 was written by Software Garden, Inc.
+// Unless otherwise specified, referring to "SocialCalc" in comments refers to this
+// JavaScript version of the code, not the SocialCalc Perl code.
+//
+*/
+
+ var SocialCalc;
+ if (!SocialCalc) SocialCalc = {}; // May be used with other SocialCalc libraries or standalone
+
+SocialCalc.FormatNumber = {};
+
+SocialCalc.FormatNumber.format_definitions = {}; // Parsed formats are stored here globally
+
+// Most constants that are often customized for localization are in the SocialCalc.Constants module.
+// If you use this module standalone, provide at least the "FormatNumber" values.
+//
+
+// The following values may be customized externally for further localization of the format definitions themselves,
+// but that would make them incompatible with other uses and is discouraged.
+//
+
+SocialCalc.FormatNumber.separatorchar = ",";
+SocialCalc.FormatNumber.decimalchar = ".";
+SocialCalc.FormatNumber.daynames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
+SocialCalc.FormatNumber.daynames3 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
+SocialCalc.FormatNumber.monthnames3 = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
+SocialCalc.FormatNumber.monthnames = ["January", "February", "March", "April", "May", "June", "July", "August", "September",
+ "October", "November", "December"];
+
+SocialCalc.FormatNumber.allowedcolors =
+ {BLACK: "#000000", BLUE: "#0000FF", CYAN: "#00FFFF", GREEN: "#00FF00", MAGENTA: "#FF00FF",
+ RED: "#FF0000", WHITE: "#FFFFFF", YELLOW: "#FFFF00"};
+
+SocialCalc.FormatNumber.alloweddates =
+ {H: "h]", M: "m]", MM: "mm]", S: "s]", SS: "ss]"};
+
+// Other constants
+
+SocialCalc.FormatNumber.commands =
+ {copy: 1, color: 2, integer_placeholder: 3, fraction_placeholder: 4, decimal: 5,
+ currency: 6, general:7, separator: 8, date: 9, comparison: 10, section: 11, style: 12};
+
+SocialCalc.FormatNumber.datevalues = {julian_offset: 2415019, seconds_in_a_day: 24 * 60 * 60, seconds_in_an_hour: 60 * 60};
+
+/* *******************
+
+ result = SocialCalc.FormatNumber.formatNumberWithFormat = function(rawvalue, format_string, currency_char)
+
+************************* */
+
+SocialCalc.FormatNumber.formatNumberWithFormat = function(rawvalue, format_string, currency_char) {
+
+ var scc = SocialCalc.Constants;
+ var scfn = SocialCalc.FormatNumber;
+
+ var op, operandstr, fromend, cval, operandstrlc;
+ var startval, estartval;
+ var hrs, mins, secs, ehrs, emins, esecs, ampmstr, ymd;
+ var minOK, mpos;
+ var result="";
+ var thisformat;
+ var section, gotcomparison, compop, compval, cpos, oppos;
+ var sectioninfo;
+ var i, decimalscale, scaledvalue, strvalue, strparts, integervalue, fractionvalue;
+ var integerdigits2, integerpos, fractionpos, textcolor, textstyle, separatorchar, decimalchar;
+ var value; // working copy to change sign, etc.
+
+ rawvalue = rawvalue-0; // make sure a number
+ value = rawvalue;
+ if (!isFinite(value)) return "NaN";
+
+ var negativevalue = value < 0 ? 1 : 0; // determine sign, etc.
+ if (negativevalue) value = -value;
+ var zerovalue = value == 0 ? 1 : 0;
+
+ currency_char = currency_char || scc.FormatNumber_DefaultCurrency;
+
+ scfn.parse_format_string(scfn.format_definitions, format_string); // make sure format is parsed
+ thisformat = scfn.format_definitions[format_string]; // Get format structure
+
+ if (!thisformat) throw "Format not parsed error!";
+
+ section = thisformat.sectioninfo.length - 1; // get number of sections - 1
+
+ if (thisformat.hascomparison) { // has comparisons - determine which section
+ section = 0; // set to which section we will use
+ gotcomparison = 0; // this section has no comparison
+ for (cpos=0; ;cpos++) { // scan for comparisons
+ op = thisformat.operators[cpos];
+ operandstr = thisformat.operands[cpos]; // get next operator and operand
+ if (!op) { // at end with no match
+ if (gotcomparison) { // if comparison but no match
+ format_string = "General"; // use default of General
+ scfn.parse_format_string(scfn.format_definitions, format_string);
+ thisformat = scfn.format_definitions[format_string];
+ section = 0;
+ }
+ break; // if no comparision, matches on this section
+ }
+ if (op == scfn.commands.section) { // end of section
+ if (!gotcomparison) { // no comparison, so it's a match
+ break;
+ }
+ gotcomparison = 0;
+ section++; // check out next one
+ continue;
+ }
+ if (op == scfn.commands.comparison) { // found a comparison - do we meet it?
+ i=operandstr.indexOf(":");
+ compop=operandstr.substring(0,i);
+ compval=operandstr.substring(i+1)-0;
+ if ((compop == "<" && rawvalue < compval) ||
+ (compop == "<=" && rawvalue <= compval) ||
+ (compop == "=" && rawvalue == compval) ||
+ (compop == "<>" && rawvalue != compval) ||
+ (compop == ">=" && rawvalue >= compval) ||
+ (compop == ">" && rawvalue > compval)) { // a match
+ break;
+ }
+ gotcomparison = 1;
+ }
+ }
+ }
+ else if (section > 0) { // more than one section (separated by ";")
+ if (section == 1) { // two sections
+ if (negativevalue) {
+ negativevalue = 0; // sign will provided by section, not automatically
+ section = 1; // use second section for negative values
+ }
+ else {
+ section = 0; // use first for all others
+ }
+ }
+ else if (section == 2) { // three sections
+ if (negativevalue) {
+ negativevalue = 0; // sign will provided by section, not automatically
+ section = 1; // use second section for negative values
+ }
+ else if (zerovalue) {
+ section = 2; // use third section for zero values
+ }
+ else {
+ section = 0; // use first for positive
+ }
+ }
+ }
+
+ sectioninfo = thisformat.sectioninfo[section]; // look at values for our section
+
+ if (sectioninfo.commas > 0) { // scale by thousands
+ for (i=0; i<sectioninfo.commas; i++) {
+ value /= 1000;
+ }
+ }
+ if (sectioninfo.percent > 0) { // do percent scaling
+ for (i=0; i<sectioninfo.percent; i++) {
+ value *= 100;
+ }
+ }
+
+ decimalscale = 1; // cut down to required number of decimal digits
+ for (i=0; i<sectioninfo.fractiondigits; i++) {
+ decimalscale *= 10;
+ }
+ scaledvalue = Math.floor(value * decimalscale + 0.5);
+ scaledvalue = scaledvalue / decimalscale;
+
+ if (typeof scaledvalue != "number") return "NaN";
+ if (!isFinite(scaledvalue)) return "NaN";
+
+ strvalue = scaledvalue+""; // convert to string (Number.toFixed doesn't do all we need)
+
+// strvalue = value.toFixed(sectioninfo.fractiondigits); // cut down to required number of decimal digits
+ // and convert to string
+
+ if (scaledvalue == 0 && (sectioninfo.fractiondigits || sectioninfo.integerdigits)) {
+ negativevalue = 0; // no "-0" unless using multiple sections or General
+ }
+
+ if (strvalue.indexOf("e")>=0) { // converted to scientific notation
+ return rawvalue+""; // Just return plain converted raw value
+ }
+
+ strparts=strvalue.match(/^\+{0,1}(\d*)(?:\.(\d*)){0,1}$/); // get integer and fraction parts
+ if (!strparts) return "NaN"; // if not a number
+ integervalue = strparts[1];
+ if (!integervalue || integervalue=="0") integervalue="";
+ fractionvalue = strparts[2];
+ if (!fractionvalue) fractionvalue = "";
+
+ if (sectioninfo.hasdate) { // there are date placeholders
+ if (rawvalue < 0) { // bad date
+ return "??-???-??&nbsp;??:??:??";
+ }
+ startval = (rawvalue-Math.floor(rawvalue)) * scfn.datevalues.seconds_in_a_day; // get date/time parts
+ estartval = rawvalue * scfn.datevalues.seconds_in_a_day; // do elapsed time version, too
+ hrs = Math.floor(startval / scfn.datevalues.seconds_in_an_hour);
+ ehrs = Math.floor(estartval / scfn.datevalues.seconds_in_an_hour);
+ startval = startval - hrs * scfn.datevalues.seconds_in_an_hour;
+ mins = Math.floor(startval / 60);
+ emins = Math.floor(estartval / 60);
+ secs = startval - mins * 60;
+ decimalscale = 1; // round appropriately depending if there is ss.0
+ for (i=0; i<sectioninfo.fractiondigits; i++) {
+ decimalscale *= 10;
+ }
+ secs = Math.floor(secs * decimalscale + 0.5);
+ secs = secs / decimalscale;
+ esecs = Math.floor(estartval * decimalscale + 0.5);
+ esecs = esecs / decimalscale;
+ if (secs >= 60) { // handle round up into next second, minute, etc.
+ secs = 0;
+ mins++; emins++;
+ if (mins >= 60) {
+ mins = 0;
+ hrs++; ehrs++;
+ if (hrs >= 24) {
+ hrs = 0;
+ rawvalue++;
+ }
+ }
+ }
+ fractionvalue = (secs-Math.floor(secs))+""; // for "hh:mm:ss.000"
+ fractionvalue = fractionvalue.substring(2); // skip "0."
+
+ ymd = SocialCalc.FormatNumber.convert_date_julian_to_gregorian(Math.floor(rawvalue+scfn.datevalues.julian_offset));
+
+ minOK = 0; // says "m" can be minutes if true
+ mspos = sectioninfo.sectionstart; // m scan position in ops
+ for ( ; ; mspos++) { // scan for "m" and "mm" to see if any minutes fields, and am/pm
+ op = thisformat.operators[mspos];
+ operandstr = thisformat.operands[mspos]; // get next operator and operand
+ if (!op) break; // don't go past end
+ if (op==scfn.commands.section) break;
+ if (op==scfn.commands.date) {
+ if ((operandstr.toLowerCase()=="am/pm" || operandstr.toLowerCase()=="a/p") && !ampmstr) {
+ if (hrs >= 12) {
+ hrs -= 12;
+ ampmstr = operandstr.toLowerCase()=="a/p" ? scc.s_FormatNumber_pm1 : scc.s_FormatNumber_pm; // "P" : "PM";
+ }
+ else {
+ ampmstr = operandstr.toLowerCase()=="a/p" ? scc.s_FormatNumber_am1 : scc.s_FormatNumber_am; // "A" : "AM";
+ }
+ if (operandstr.indexOf(ampmstr)<0)
+ ampmstr = ampmstr.toLowerCase(); // have case match case in format
+ }
+ if (minOK && (operandstr=="m" || operandstr=="mm")) {
+ thisformat.operands[mspos] += "in"; // turn into "min" or "mmin"
+ }
+ if (operandstr.charAt(0)=="h") {
+ minOK = 1; // m following h or hh or [h] is minutes not months
+ }
+ else {
+ minOK = 0;
+ }
+ }
+ else if (op!=scfn.commands.copy) { // copying chars can be between h and m
+ minOK = 0;
+ }
+ }
+ minOK = 0;
+ for (--mspos; ; mspos--) { // scan other way for s after m
+ op = thisformat.operators[mspos];
+ operandstr = thisformat.operands[mspos]; // get next operator and operand
+ if (!op) break; // don't go past end
+ if (op==scfn.commands.section) break;
+ if (op==scfn.commands.date) {
+ if (minOK && (operandstr=="m" || operandstr=="mm")) {
+ thisformat.operands[mspos] += "in"; // turn into "min" or "mmin"
+ }
+ if (operandstr=="ss") {
+ minOK = 1; // m before ss is minutes not months
+ }
+ else {
+ minOK = 0;
+ }
+ }
+ else if (op!=scfn.commands.copy) { // copying chars can be between ss and m
+ minOK = 0;
+ }
+ }
+ }
+
+ integerdigits2 = 0; // init counters, etc.
+ integerpos = 0;
+ fractionpos = 0;
+ textcolor = "";
+ textstyle = "";
+ separatorchar = scc.FormatNumber_separatorchar;
+ if (separatorchar.indexOf(" ")>=0) separatorchar = separatorchar.replace(/ /g, "&nbsp;");
+ decimalchar = scc.FormatNumber_decimalchar;
+ if (decimalchar.indexOf(" ")>=0) decimalchar = decimalchar.replace(/ /g, "&nbsp;");
+
+ oppos = sectioninfo.sectionstart;
+
+ while (op = thisformat.operators[oppos]) { // execute format
+ operandstr = thisformat.operands[oppos++]; // get next operator and operand
+
+ if (op == scfn.commands.copy) { // put char in result
+ result += operandstr;
+ }
+
+ else if (op == scfn.commands.color) { // set color
+ textcolor = operandstr;
+ }
+
+ else if (op == scfn.commands.style) { // set style
+ textstyle = operandstr;
+ }
+
+ else if (op == scfn.commands.integer_placeholder) { // insert number part
+ if (negativevalue) {
+ result += "-";
+ negativevalue = 0;
+ }
+ integerdigits2++;
+ if (integerdigits2 == 1) { // first one
+ if (integervalue.length > sectioninfo.integerdigits) { // see if integer wider than field
+ for (;integerpos < (integervalue.length - sectioninfo.integerdigits); integerpos++) {
+ result += integervalue.charAt(integerpos);
+ if (sectioninfo.thousandssep) { // see if this is a separator position
+ fromend = integervalue.length - integerpos - 1;
+ if (fromend > 2 && fromend % 3 == 0) {
+ result += separatorchar;
+ }
+ }
+ }
+ }
+ }
+ if (integervalue.length < sectioninfo.integerdigits
+ && integerdigits2 <= sectioninfo.integerdigits - integervalue.length) { // field is wider than value
+ if (operandstr == "0" || operandstr == "?") { // fill with appropriate characters
+ result += operandstr == "0" ? "0" : "&nbsp;";
+ if (sectioninfo.thousandssep) { // see if this is a separator position
+ fromend = sectioninfo.integerdigits - integerdigits2;
+ if (fromend > 2 && fromend % 3 == 0) {
+ result += separatorchar;
+ }
+ }
+ }
+ }
+ else { // normal integer digit - add it
+ result += integervalue.charAt(integerpos);
+ if (sectioninfo.thousandssep) { // see if this is a separator position
+ fromend = integervalue.length - integerpos - 1;
+ if (fromend > 2 && fromend % 3 == 0) {
+ result += separatorchar;
+ }
+ }
+ integerpos++;
+ }
+ }
+ else if (op == scfn.commands.fraction_placeholder) { // add fraction part of number
+ if (fractionpos >= fractionvalue.length) {
+ if (operandstr == "0" || operandstr == "?") {
+ result += operandstr == "0" ? "0" : "&nbsp;";
+ }
+ }
+ else {
+ result += fractionvalue.charAt(fractionpos);
+ }
+ fractionpos++;
+ }
+
+ else if (op == scfn.commands.decimal) { // decimal point
+ if (negativevalue) {
+ result += "-";
+ negativevalue = 0;
+ }
+ result += decimalchar;
+ }
+
+ else if (op == scfn.commands.currency) { // currency symbol
+ if (negativevalue) {
+ result += "-";
+ negativevalue = 0;
+ }
+ result += operandstr;
+ }
+
+ else if (op == scfn.commands.general) { // insert "General" conversion
+
+ // *** Cut down number of significant digits to avoid floating point artifacts:
+
+ if (value!=0) { // only if non-zero
+ var factor = Math.floor(Math.LOG10E * Math.log(value)); // get integer magnitude as a power of 10
+ factor = Math.pow(10, 13-factor); // turn into scaling factor
+ value = Math.floor(factor * value + 0.5)/factor; // scale positive value, round, undo scaling
+ if (!isFinite(value)) return "NaN";
+ }
+ if (negativevalue) {
+ result += "-";
+ }
+ strvalue = value+""; // convert original value to string
+ if (strvalue.indexOf("e")>=0) { // converted to scientific notation
+ result += strvalue;
+ continue;
+ }
+ strparts=strvalue.match(/^\+{0,1}(\d*)(?:\.(\d*)){0,1}$/); // get integer and fraction parts
+ integervalue = strparts[1];
+ if (!integervalue || integervalue=="0") integervalue="";
+ fractionvalue = strparts[2];
+ if (!fractionvalue) fractionvalue = "";
+ integerpos = 0;
+ fractionpos = 0;
+ if (integervalue.length) {
+ for (;integerpos < integervalue.length; integerpos++) {
+ result += integervalue.charAt(integerpos);
+ if (sectioninfo.thousandssep) { // see if this is a separator position
+ fromend = integervalue.length - integerpos - 1;
+ if (fromend > 2 && fromend % 3 == 0) {
+ result += separatorchar;
+ }
+ }
+ }
+ }
+ else {
+ result += "0";
+ }
+ if (fractionvalue.length) {
+ result += decimalchar;
+ for (;fractionpos < fractionvalue.length; fractionpos++) {
+ result += fractionvalue.charAt(fractionpos);
+ }
+ }
+ }
+ else if (op==scfn.commands.date) { // date placeholder
+ operandstrlc = operandstr.toLowerCase();
+ if (operandstrlc=="y" || operandstrlc=="yy") {
+ result += (ymd.year+"").substring(2);
+ }
+ else if (operandstrlc=="yyyy") {
+ result += ymd.year+"";
+ }
+ else if (operandstrlc=="d") {
+ result += ymd.day+"";
+ }
+ else if (operandstrlc=="dd") {
+ cval = 1000 + ymd.day;
+ result += (cval+"").substr(2);
+ }
+ else if (operandstrlc=="ddd") {
+ cval = Math.floor(rawvalue+6) % 7;
+ result += scc.s_FormatNumber_daynames3[cval];
+ }
+ else if (operandstrlc=="dddd") {
+ cval = Math.floor(rawvalue+6) % 7;
+ result += scc.s_FormatNumber_daynames[cval];
+ }
+ else if (operandstrlc=="m") {
+ result += ymd.month+"";
+ }
+ else if (operandstrlc=="mm") {
+ cval = 1000 + ymd.month;
+ result += (cval+"").substr(2);
+ }
+ else if (operandstrlc=="mmm") {
+ result += scc.s_FormatNumber_monthnames3[ymd.month-1];
+ }
+ else if (operandstrlc=="mmmm") {
+ result += scc.s_FormatNumber_monthnames[ymd.month-1];
+ }
+ else if (operandstrlc=="mmmmm") {
+ result += scc.s_FormatNumber_monthnames[ymd.month-1].charAt(0);
+ }
+ else if (operandstrlc=="h") {
+ result += hrs+"";
+ }
+ else if (operandstrlc=="h]") {
+ result += ehrs+"";
+ }
+ else if (operandstrlc=="mmin") {
+ cval = (1000 + mins)+"";
+ result += cval.substr(2);
+ }
+ else if (operandstrlc=="mm]") {
+ if (emins < 100) {
+ cval = (1000 + emins)+"";
+ result += cval.substr(2);
+ }
+ else {
+ result += emins+"";
+ }
+ }
+ else if (operandstrlc=="min") {
+ result += mins+"";
+ }
+ else if (operandstrlc=="m]") {
+ result += emins+"";
+ }
+ else if (operandstrlc=="hh") {
+ cval = (1000 + hrs)+"";
+ result += cval.substr(2);
+ }
+ else if (operandstrlc=="s") {
+ cval = Math.floor(secs);
+ result += cval+"";
+ }
+ else if (operandstrlc=="ss") {
+ cval = (1000 + Math.floor(secs))+"";
+ result += cval.substr(2);
+ }
+ else if (operandstrlc=="am/pm" || operandstrlc=="a/p") {
+ result += ampmstr;
+ }
+ else if (operandstrlc=="ss]") {
+ if (esecs < 100) {
+ cval = (1000 + Math.floor(esecs))+"";
+ result += cval.substr(2);
+ }
+ else {
+ cval = Math.floor(esecs);
+ result += cval+"";
+ }
+ }
+ }
+ else if (op == scfn.commands.section) { // end of section
+ break;
+ }
+
+ else if (op == scfn.commands.comparison) { // ignore
+ continue;
+ }
+
+ else {
+ result += "!! Parse error !!";
+ }
+ }
+
+ if (textcolor) {
+ result = '<span style="color:'+textcolor+';">'+result+'</span>';
+ }
+ if (textstyle) {
+ result = '<span style="'+textstyle+';">'+result+'</span>';
+ }
+
+ return result;
+
+ };
+
+/* *******************
+
+ SocialCalc.FormatNumber.parse_format_string(format_defs, format_string)
+
+ Takes a format string (e.g., "#,##0.00_);(#,##0.00)") and fills in format_defs with the parsed info
+
+ format_defs
+ ["#,##0.0"]->{} - elements in the hash are one hash for each format
+ .operators->[] - array of operators from parsing the format string (each a number)
+ .operands->[] - array of corresponding operators (each usually a string)
+ .sectioninfo->[] - one hash for each section of the format
+ .start
+ .integerdigits
+ .fractiondigits
+ .commas
+ .percent
+ .thousandssep
+ .hasdates
+ .hascomparison - true if any section has [<100], etc.