<commit_before>var sdk_dev_scrpipts = [
    "../../../../sdkjs/common/AllFonts.js",
    "../../../../sdkjs/common/browser.js",
	"../../../../sdkjs/common/commonDefines.js",
	"../../../../sdkjs/common/downloaderfiles.js",
	"../../../../sdkjs/common/docscoapicommon.js",
    "../../../../sdkjs/common/docscoapi.js",
	"../../../../sdkjs/common/apiCommon.js",
	"../../../../sdkjs/common/SerializeCommonWordExcel.js",
    "../../../../sdkjs/common/editorscommon.js",
	"../../../../sdkjs/common/HistoryCommon.js",
	"../../../../sdkjs/common/TableId.js",
	"../../../../sdkjs/common/TableIdChanges.js",
	"../../../../sdkjs/common/NumFormat.js",
	"../../../../sdkjs/common/SerializeChart.js",
	"../../../../sdkjs/common/AdvancedOptions.js",
	"../../../../sdkjs/common/FontsFreeType/font_engine.js",
    "../../../../sdkjs/common/FontsFreeType/FontFile.js",
	"../../../../sdkjs/common/FontsFreeType/font_map.js",
    "../../../../sdkjs/common/FontsFreeType/FontManager.js",
	"../../../../sdkjs/word/Editor/FontClassification.js",
	"../../../../sdkjs/common/Drawings/Metafile.js",
	"../../../../sdkjs/common/FontsFreeType/TextMeasurer.js",
	"../../../../sdkjs/common/Drawings/WorkEvents.js",
	"../../../../sdkjs/cell/model/History.js",
	"../../../../sdkjs/common/Shapes/EditorSettings.js",
	"../../../../sdkjs/common/Shapes/Serialize.js",
	"../../../../sdkjs/common/Shapes/SerializeWriter.js",
	"../../../../sdkjs/common/Drawings/Hit.js",
	"../../../../sdkjs/common/Drawings/ArcTo.js",
	"../../../../sdkjs/common/Drawings/ColorArray.js",
	"../../../../sdkjs/common/Drawings/CommonController.js",
	"../../../../sdkjs/common/Drawings/States.js",
	"../../../../sdkjs/common/Drawings/DrawingsChanges.js",
	"../../../../sdkjs/common/Drawings/Format/CreateGeometry.js",
	"../../../../sdkjs/common/Drawings/Format/Geometry.js",
	"../../../../sdkjs/common/Drawings/Format/Format.js",
	"../../../../sdkjs/common/Drawings/Format/GraphicObjectBase.js",
	"../../../../sdkjs/common/Drawings/Format/Shape.js",
	"../../../../sdkjs/common/Drawings/Format/CnxShape.js",
	"../../../../sdkjs/common/Drawings/Format/Path.js",
	"../../../../sdkjs/common/Drawings/Format/Image.js",
	"../../../../sdkjs/common/Drawings/Format/GroupShape.js",
	"../../../../sdkjs/common/Drawings/Format/ChartSpace.js",
	"../../../../sdkjs/common/Drawings/Format/ChartFormat.js",
	"../../../../sdkjs/common/Drawings/Format/TextBody.js",
	"../../../../sdkjs/common/Drawings/Format/GraphicFrame.js",
	"../../../../sdkjs/common/Charts/charts.js",
	"../../../../sdkjs/common/Charts/DrawingArea.js",
	"../../../../sdkjs/common/Charts/DrawingObjects.js",
	"../../../../sdkjs/common/Charts/3DTransformation.js",
	"../../../../sdkjs/common/Charts/ChartsDrawer.js",
	"../../../../sdkjs/common/Drawings/TrackObjects/AdjustmentTracks.js",
    "../../../../sdkjs/common/Drawings/TrackObjects/MoveTracks.js",
    "../../../../sdkjs/common/Drawings/TrackObjects/NewShapeTracks.js",
    "../../../../sdkjs/common/Drawings/TrackObjects/PolyLine.js",
	"../../../../sdkjs/common/Drawings/TrackObjects/ResizeTracks.js",
	"../../../../sdkjs/common/Drawings/TrackObjects/RotateTracks.js",
	"../../../../sdkjs/common/Drawings/TrackObjects/Spline.js",
	"../../../../sdkjs/common/Drawings/TrackObjects/ConnectorTrack.js",
	"../../../../sdkjs/common/Drawings/DrawingObjectsHandlers.js",
	"../../../../sdkjs/common/Drawings/TextDrawer.js",
	"../../../../sdkjs/common/Drawings/Externals.js",
	"../../../../sdkjs/common/GlobalLoaders.js",
	"../../../../sdkjs/common/CollaborativeEditingBase.js",
	"../../../../sdkjs/common/Controls.js",
	"../../../../sdkjs/common/Overlay.js",
	"../../../../sdkjs/common/Drawings/HatchPattern.js",
	"../../../../sdkjs/common/scroll.js",
	"../../../../sdkjs/common/Scrolls/iscroll.js",
	"../../../../sdkjs/common/Scrolls/mobileTouchManagerBase.js",
	"../../../../sdkjs/common/wordcopypaste.js",
	"../../../../sdkjs/cell/apiDefines.js",
	"../../../../sdkjs/cell/document/empty-workbook.js",
	"../../../../sdkjs/cell/utils/utils.js",
	"../../../../sdkjs/cell/model/UndoRedo.js",
	"../../../../sdkjs/cell/model/clipboard.js",
    "../../../../sdkjs/cell/model/autofilters.js",
	"../../../../sdkjs/cell/graphics/DrawingContext.js",
    "../../../../sdkjs/cell/graphics/pdfprinter.js",
    "../../../../sdkjs/cell/model/CollaborativeEditing.js",
    "../../../../sdkjs/cell/model/ConditionalFormatting.js",
    "../../../../sdkjs/cell/model/FormulaObjects/parserFormula.js",
    "../../../../sdkjs/cell/model/FormulaObjects/_xlfnFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/dateandtimeFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/engineeringFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/cubeFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/databaseFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/textanddataFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/statisticalFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/financialFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/mathematicFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/lookupandreferenceFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/informationFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/logicalFunctions.js",
	"../../../../sdkjs/cell/model/CellComment.js",
	"../../../../sdkjs/cell/model/WorkbookElems.js",
	"../../../../sdkjs/cell/model/Workbook.js",
	"../../../../sdkjs/cell/model/Serialize.js",
	"../../../../sdkjs/cell/model/CellInfo.js",
	"../../../../sdkjs/cell/view/mobileTouch.js",
	"../../../../sdkjs/cell/view/DrawingObjectsController.js",
    "../../../../sdkjs/cell/view/StringRender.js",
    "../../../../sdkjs/cell/view/CellTextRender.js",
    "../../../../sdkjs/cell/view/CellEditorView.js",
    "../../../../sdkjs/cell/view/HandlerList.js",
    "../../../../sdkjs/cell/view/EventsController.js",
    "../../../../sdkjs/cell/view/WorkbookView.js",
	"../../../../sdkjs/cell/view/WorksheetView.js",
	"../../../../sdkjs/cell/model/DrawingObjects/Graphics.js",
	"../../../../sdkjs/cell/model/DrawingObjects/ShapeDrawer.js",
	"../../../../sdkjs/cell/model/DrawingObjects/DrawingDocument.js",
	"../../../../sdkjs/cell/model/DrawingObjects/GlobalCounters.js",
	"../../../../sdkjs/cell/model/DrawingObjects/Format/ShapePrototype.js",
	"../../../../sdkjs/cell/model/DrawingObjects/Format/ImagePrototype.js",
    "../../../../sdkjs/cell/model/DrawingObjects/Format/GroupPrototype.js",
    "../../../../sdkjs/cell/model/DrawingObjects/Format/ChartSpacePrototype.js",
    "../../../../sdkjs/common/apiBase.js",
    "../../../../sdkjs/cell/api.js",
    "../../../../sdkjs/common/Private/license.js",
    "../../../../sdkjs/cell/Private/comments.js",
	"../../../../sdkjs/word/Editor/Common.js",
	"../../../../sdkjs/word/Editor/DocumentContentElementBase.js",
    "../../../../sdkjs/word/Editor/Comments.js",
	"../../../../sdkjs/word/Editor/CommentsChanges.js",
	"../../../../sdkjs/word/Editor/Styles.js",
	"../../../../sdkjs/word/Editor/StylesChanges.js",
	"../../../../sdkjs/word/Editor/RevisionsChange.js",
	"../../../../sdkjs/word/Editor/ParagraphContent.js",
	"../../../../sdkjs/word/Editor/Paragraph/ParaTextPr.js",
	"../../../../sdkjs/word/Editor/Paragraph/ParaTextPrChanges.js",
	"../../../../sdkjs/word/Editor/Paragraph/ParaDrawing.js",
	"../../../../sdkjs/word/Editor/Paragraph/ParaDrawingChanges.js",
	"../../../../sdkjs/word/Editor/Paragraph.js",
	"../../../../sdkjs/word/Editor/ParagraphChanges.js",
	"../../../../sdkjs/word/Editor/DocumentContentBase.js",
	"../../../../sdkjs/word/Editor/Document.js",
	"../../../../sdkjs/word/Editor/DocumentChanges.js",
	"../../../../sdkjs/word/Editor/DocumentContent.js",
	"../../../../sdkjs/word/Editor/DocumentContentChanges.js",
	"../../../../sdkjs/word/Editor/DocumentControllerBase.js",
	"../../../../sdkjs/word/Editor/LogicDocumentController.js",
	"../../../../sdkjs/word/Editor/DrawingsController.js",
	"../../../../sdkjs/word/Editor/HeaderFooterController.js",
    "../../../../sdkjs/word/Editor/FlowObjects.js",
	"../../../../sdkjs/word/Editor/ParagraphContentBase.js",
	"../../../../sdkjs/word/Editor/Hyperlink.js",
	"../../../../sdkjs/word/Editor/HyperlinkChanges.js",
	"../../../../sdkjs/word/Editor/Field.js",
	"../../../../sdkjs/word/Editor/FieldChanges.js",
	"../../../../sdkjs/word/Editor/Run.js",
	"../../../../sdkjs/word/Editor/RunChanges.js",
    "../../../../sdkjs/word/Editor/Math.js",
	"../../../../sdkjs/word/Editor/MathChanges.js",
	"../../../../sdkjs/word/Editor/Paragraph_Recalculate.js",
	"../../../../sdkjs/word/Editor/Sections.js",
	"../../../../sdkjs/word/Editor/SectionsChanges.js",
    "../../../../sdkjs/word/Editor/Numbering.js",
	"../../../../sdkjs/word/Editor/NumberingChanges.js",
    "../../../../sdkjs/word/Editor/HeaderFooter.js",
    "../../../../sdkjs/word/Editor/Table.js",
	"../../../../sdkjs/word/Editor/Table/TableChanges.js",
    "../../../../sdkjs/word/Editor/Table/TableRecalculate.js",
    "../../../../sdkjs/word/Editor/Table/TableDraw.js",
    "../../../../sdkjs/word/Editor/Table/TableRow.js",
	"../../../../sdkjs/word/Editor/Table/TableRowChanges.js",
    "../../../../sdkjs/word/Editor/Table/TableCell.js",
	"../../../../sdkjs/word/Editor/Table/TableCellChanges.js",
	"../../../../sdkjs/word/Editor/StructuredDocumentTags/BlockLevel.js",
	"../../../../sdkjs/word/Editor/StructuredDocumentTags/InlineLevel.js",
	"../../../../sdkjs/word/Editor/StructuredDocumentTags/SdtPr.js",
	"../../../../sdkjs/word/Editor/StructuredDocumentTags/SdtPrChanges.js",
    "../../../../sdkjs/word/Editor/Serialize2.js",
    "../../../../sdkjs/word/Editor/Spelling.js",
	"../../../../sdkjs/word/Editor/Footnotes.js",
	"../../../../sdkjs/word/Editor/FootnotesChanges.js",
	"../../../../sdkjs/word/Editor/FootEndNote.js",
	"../../../../sdkjs/word/Editor/GraphicObjects/WrapManager.js",
	"../../../../sdkjs/word/Math/mathTypes.js",
    "../../../../sdkjs/word/Math/mathText.js",
    "../../../../sdkjs/word/Math/mathContent.js",
    "../../../../sdkjs/word/Math/base.js",
    "../../../../sdkjs/word/Math/fraction.js",
    "../../../../sdkjs/word/Math/degree.js",
    "../../../../sdkjs/word/Math/matrix.js",
    "../../../../sdkjs/word/Math/limit.js",
    "../../../../sdkjs/word/Math/nary.js",
    "../../../../sdkjs/word/Math/radical.js",
    "../../../../sdkjs/word/Math/operators.js",
    "../../../../sdkjs/word/Math/accent.js",
    "../../../../sdkjs/word/Math/borderBox.js",
    "../../../../sdkjs/word/apiCommon.js",
	"../../../../sdkjs/common/applyDocumentChanges.js",
    "../../../../sdkjs/word/apiBuilder.js",
    "../../../../sdkjs/slide/apiBuilder.js",
	"../../../../sdkjs/cell/apiBuilder.js",
    "../../../../sdkjs/common/Drawings/Format/OleObject.js",
	"../../../../sdkjs/common/Drawings/Format/DrawingContent.js",
    "../../../../sdkjs/common/clipboard_base.js",
    "../../../../sdkjs/common/plugins.js",
    "../../../../sdkjs/common/text_input.js"
];<commit_msg>add easysax.js, openxml.js<commit_after>var sdk_dev_scrpipts = [
    "../../../../sdkjs/common/AllFonts.js",
    "../../../../sdkjs/common/browser.js",
	"../../../../sdkjs/common/commonDefines.js",
	"../../../../sdkjs/common/downloaderfiles.js",
	"../../../../sdkjs/common/docscoapicommon.js",
    "../../../../sdkjs/common/docscoapi.js",
	"../../../../sdkjs/common/apiCommon.js",
	"../../../../sdkjs/common/SerializeCommonWordExcel.js",
    "../../../../sdkjs/common/editorscommon.js",
	"../../../../sdkjs/common/HistoryCommon.js",
	"../../../../sdkjs/common/TableId.js",
	"../../../../sdkjs/common/TableIdChanges.js",
	"../../../../sdkjs/common/NumFormat.js",
	"../../../../sdkjs/common/SerializeChart.js",
	"../../../../sdkjs/common/AdvancedOptions.js",
	"../../../../sdkjs/common/FontsFreeType/font_engine.js",
    "../../../../sdkjs/common/FontsFreeType/FontFile.js",
	"../../../../sdkjs/common/FontsFreeType/font_map.js",
    "../../../../sdkjs/common/FontsFreeType/FontManager.js",
	"../../../../sdkjs/word/Editor/FontClassification.js",
	"../../../../sdkjs/common/Drawings/Metafile.js",
	"../../../../sdkjs/common/FontsFreeType/TextMeasurer.js",
	"../../../../sdkjs/common/Drawings/WorkEvents.js",
	"../../../../sdkjs/cell/model/History.js",
	"../../../../sdkjs/common/Shapes/EditorSettings.js",
	"../../../../sdkjs/common/Shapes/Serialize.js",
	"../../../../sdkjs/common/Shapes/SerializeWriter.js",
	"../../../../sdkjs/common/Drawings/Hit.js",
	"../../../../sdkjs/common/Drawings/ArcTo.js",
	"../../../../sdkjs/common/Drawings/ColorArray.js",
	"../../../../sdkjs/common/Drawings/CommonController.js",
	"../../../../sdkjs/common/Drawings/States.js",
	"../../../../sdkjs/common/Drawings/DrawingsChanges.js",
	"../../../../sdkjs/common/Drawings/Format/CreateGeometry.js",
	"../../../../sdkjs/common/Drawings/Format/Geometry.js",
	"../../../../sdkjs/common/Drawings/Format/Format.js",
	"../../../../sdkjs/common/Drawings/Format/GraphicObjectBase.js",
	"../../../../sdkjs/common/Drawings/Format/Shape.js",
	"../../../../sdkjs/common/Drawings/Format/CnxShape.js",
	"../../../../sdkjs/common/Drawings/Format/Path.js",
	"../../../../sdkjs/common/Drawings/Format/Image.js",
	"../../../../sdkjs/common/Drawings/Format/GroupShape.js",
	"../../../../sdkjs/common/Drawings/Format/ChartSpace.js",
	"../../../../sdkjs/common/Drawings/Format/ChartFormat.js",
	"../../../../sdkjs/common/Drawings/Format/TextBody.js",
	"../../../../sdkjs/common/Drawings/Format/GraphicFrame.js",
	"../../../../sdkjs/common/Charts/charts.js",
	"../../../../sdkjs/common/Charts/DrawingArea.js",
	"../../../../sdkjs/common/Charts/DrawingObjects.js",
	"../../../../sdkjs/common/Charts/3DTransformation.js",
	"../../../../sdkjs/common/Charts/ChartsDrawer.js",
	"../../../../sdkjs/common/Drawings/TrackObjects/AdjustmentTracks.js",
    "../../../../sdkjs/common/Drawings/TrackObjects/MoveTracks.js",
    "../../../../sdkjs/common/Drawings/TrackObjects/NewShapeTracks.js",
    "../../../../sdkjs/common/Drawings/TrackObjects/PolyLine.js",
	"../../../../sdkjs/common/Drawings/TrackObjects/ResizeTracks.js",
	"../../../../sdkjs/common/Drawings/TrackObjects/RotateTracks.js",
	"../../../../sdkjs/common/Drawings/TrackObjects/Spline.js",
	"../../../../sdkjs/common/Drawings/TrackObjects/ConnectorTrack.js",
	"../../../../sdkjs/common/Drawings/DrawingObjectsHandlers.js",
	"../../../../sdkjs/common/Drawings/TextDrawer.js",
	"../../../../sdkjs/common/Drawings/Externals.js",
	"../../../../sdkjs/common/GlobalLoaders.js",
	"../../../../sdkjs/common/CollaborativeEditingBase.js",
	"../../../../sdkjs/common/Controls.js",
	"../../../../sdkjs/common/Overlay.js",
	"../../../../sdkjs/common/Drawings/HatchPattern.js",
	"../../../../sdkjs/common/scroll.js",
	"../../../../sdkjs/common/Scrolls/iscroll.js",
	"../../../../sdkjs/common/Scrolls/mobileTouchManagerBase.js",
	"../../../../sdkjs/common/wordcopypaste.js",
	"../../../../sdkjs/cell/apiDefines.js",
	"../../../../sdkjs/cell/document/empty-workbook.js",
	"../../../../sdkjs/cell/utils/utils.js",
	"../../../../sdkjs/cell/model/UndoRedo.js",
	"../../../../sdkjs/cell/model/clipboard.js",
    "../../../../sdkjs/cell/model/autofilters.js",
	"../../../../sdkjs/cell/graphics/DrawingContext.js",
    "../../../../sdkjs/cell/graphics/pdfprinter.js",
    "../../../../sdkjs/cell/model/CollaborativeEditing.js",
    "../../../../sdkjs/cell/model/ConditionalFormatting.js",
    "../../../../sdkjs/cell/model/FormulaObjects/parserFormula.js",
    "../../../../sdkjs/cell/model/FormulaObjects/_xlfnFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/dateandtimeFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/engineeringFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/cubeFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/databaseFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/textanddataFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/statisticalFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/financialFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/mathematicFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/lookupandreferenceFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/informationFunctions.js",
    "../../../../sdkjs/cell/model/FormulaObjects/logicalFunctions.js",
	"../../../../sdkjs/cell/model/CellComment.js",
	"../../../../sdkjs/cell/model/WorkbookElems.js",
	"../../../../sdkjs/cell/model/Workbook.js",
	"../../../../sdkjs/cell/model/Serialize.js",
	"../../../../sdkjs/cell/model/CellInfo.js",
	"../../../../sdkjs/cell/view/mobileTouch.js",
	"../../../../sdkjs/cell/view/DrawingObjectsController.js",
    "../../../../sdkjs/cell/view/StringRender.js",
    "../../../../sdkjs/cell/view/CellTextRender.js",
    "../../../../sdkjs/cell/view/CellEditorView.js",
    "../../../../sdkjs/cell/view/HandlerList.js",
    "../../../../sdkjs/cell/view/EventsController.js",
    "../../../../sdkjs/cell/view/WorkbookView.js",
	"../../../../sdkjs/cell/view/WorksheetView.js",
	"../../../../sdkjs/cell/model/DrawingObjects/Graphics.js",
	"../../../../sdkjs/cell/model/DrawingObjects/ShapeDrawer.js",
	"../../../../sdkjs/cell/model/DrawingObjects/DrawingDocument.js",
	"../../../../sdkjs/cell/model/DrawingObjects/GlobalCounters.js",
	"../../../../sdkjs/cell/model/DrawingObjects/Format/ShapePrototype.js",
	"../../../../sdkjs/cell/model/DrawingObjects/Format/ImagePrototype.js",
    "../../../../sdkjs/cell/model/DrawingObjects/Format/GroupPrototype.js",
    "../../../../sdkjs/cell/model/DrawingObjects/Format/ChartSpacePrototype.js",
    "../../../../sdkjs/common/apiBase.js",
    "../../../../sdkjs/cell/api.js",
    "../../../../sdkjs/common/Private/license.js",
    "../../../../sdkjs/cell/Private/comments.js",
	"../../../../sdkjs/word/Editor/Common.js",
	"../../../../sdkjs/word/Editor/DocumentContentElementBase.js",
    "../../../../sdkjs/word/Editor/Comments.js",
	"../../../../sdkjs/word/Editor/CommentsChanges.js",
	"../../../../sdkjs/word/Editor/Styles.js",
	"../../../../sdkjs/word/Editor/StylesChanges.js",
	"../../../../sdkjs/word/Editor/RevisionsChange.js",
	"../../../../sdkjs/word/Editor/ParagraphContent.js",
	"../../../../sdkjs/word/Editor/Paragraph/ParaTextPr.js",
	"../../../../sdkjs/word/Editor/Paragraph/ParaTextPrChanges.js",
	"../../../../sdkjs/word/Editor/Paragraph/ParaDrawing.js",
	"../../../../sdkjs/word/Editor/Paragraph/ParaDrawingChanges.js",
	"../../../../sdkjs/word/Editor/Paragraph.js",
	"../../../../sdkjs/word/Editor/ParagraphChanges.js",
	"../../../../sdkjs/word/Editor/DocumentContentBase.js",
	"../../../../sdkjs/word/Editor/Document.js",
	"../../../../sdkjs/word/Editor/DocumentChanges.js",
	"../../../../sdkjs/word/Editor/DocumentContent.js",
	"../../../../sdkjs/word/Editor/DocumentContentChanges.js",
	"../../../../sdkjs/word/Editor/DocumentControllerBase.js",
	"../../../../sdkjs/word/Editor/LogicDocumentController.js",
	"../../../../sdkjs/word/Editor/DrawingsController.js",
	"../../../../sdkjs/word/Editor/HeaderFooterController.js",
    "../../../../sdkjs/word/Editor/FlowObjects.js",
	"../../../../sdkjs/word/Editor/ParagraphContentBase.js",
	"../../../../sdkjs/word/Editor/Hyperlink.js",
	"../../../../sdkjs/word/Editor/HyperlinkChanges.js",
	"../../../../sdkjs/word/Editor/Field.js",
	"../../../../sdkjs/word/Editor/FieldChanges.js",
	"../../../../sdkjs/word/Editor/Run.js",
	"../../../../sdkjs/word/Editor/RunChanges.js",
    "../../../../sdkjs/word/Editor/Math.js",
	"../../../../sdkjs/word/Editor/MathChanges.js",
	"../../../../sdkjs/word/Editor/Paragraph_Recalculate.js",
	"../../../../sdkjs/word/Editor/Sections.js",
	"../../../../sdkjs/word/Editor/SectionsChanges.js",
    "../../../../sdkjs/word/Editor/Numbering.js",
	"../../../../sdkjs/word/Editor/NumberingChanges.js",
    "../../../../sdkjs/word/Editor/HeaderFooter.js",
    "../../../../sdkjs/word/Editor/Table.js",
	"../../../../sdkjs/word/Editor/Table/TableChanges.js",
    "../../../../sdkjs/word/Editor/Table/TableRecalculate.js",
    "../../../../sdkjs/word/Editor/Table/TableDraw.js",
    "../../../../sdkjs/word/Editor/Table/TableRow.js",
	"../../../../sdkjs/word/Editor/Table/TableRowChanges.js",
    "../../../../sdkjs/word/Editor/Table/TableCell.js",
	"../../../../sdkjs/word/Editor/Table/TableCellChanges.js",
	"../../../../sdkjs/word/Editor/StructuredDocumentTags/BlockLevel.js",
	"../../../../sdkjs/word/Editor/StructuredDocumentTags/InlineLevel.js",
	"../../../../sdkjs/word/Editor/StructuredDocumentTags/SdtPr.js",
	"../../../../sdkjs/word/Editor/StructuredDocumentTags/SdtPrChanges.js",
    "../../../../sdkjs/word/Editor/Serialize2.js",
    "../../../../sdkjs/word/Editor/Spelling.js",
	"../../../../sdkjs/word/Editor/Footnotes.js",
	"../../../../sdkjs/word/Editor/FootnotesChanges.js",
	"../../../../sdkjs/word/Editor/FootEndNote.js",
	"../../../../sdkjs/word/Editor/GraphicObjects/WrapManager.js",
	"../../../../sdkjs/word/Math/mathTypes.js",
    "../../../../sdkjs/word/Math/mathText.js",
    "../../../../sdkjs/word/Math/mathContent.js",
    "../../../../sdkjs/word/Math/base.js",
    "../../../../sdkjs/word/Math/fraction.js",
    "../../../../sdkjs/word/Math/degree.js",
    "../../../../sdkjs/word/Math/matrix.js",
    "../../../../sdkjs/word/Math/limit.js",
    "../../../../sdkjs/word/Math/nary.js",
    "../../../../sdkjs/word/Math/radical.js",
    "../../../../sdkjs/word/Math/operators.js",
    "../../../../sdkjs/word/Math/accent.js",
    "../../../../sdkjs/word/Math/borderBox.js",
    "../../../../sdkjs/word/apiCommon.js",
	"../../../../sdkjs/common/applyDocumentChanges.js",
    "../../../../sdkjs/word/apiBuilder.js",
    "../../../../sdkjs/slide/apiBuilder.js",
	"../../../../sdkjs/cell/apiBuilder.js",
    "../../../../sdkjs/common/Drawings/Format/OleObject.js",
	"../../../../sdkjs/common/Drawings/Format/DrawingContent.js",
    "../../../../sdkjs/common/clipboard_base.js",
    "../../../../sdkjs/common/plugins.js",
    "../../../../sdkjs/common/text_input.js",
	"../../../../sdkjs/common/easysax.js",
	"../../../../sdkjs/common/openxml.js"
];<|endoftext|>


<commit_before>// rule engine runtime
var _WbRules = {
  requireCompleteCells: 0,
  timers: {},
  aliases: {},

  CronEntry: function (spec) {
    if (typeof spec != "string")
      throw new Error("invalid cron spec");
    this.spec = spec;
  },

  IncompleteCellCaught: (function () {
    function IncompleteCellCaught(cellName) {
      this.name = "IncompleteCellCaught";
      this.message = "incomplete cell encountered: " + cellName;
    }
    IncompleteCellCaught.prototype = Object.create(Error.prototype);
    return IncompleteCellCaught;
  })(),

  autoload: function (target, acquire, setValue) {
    return new Proxy(target, {
      get: function (o, name) {
        if (!(name in o)) {
          o[name] = acquire(name, o);
        }
        return o[name];
      },
      set: function (o, name, value) {
        throw new Error("setting unsupported proxy value: " + name);
      }
    });
  },

  wrapDevice: function (name) {
    var cells = {};
    function ensureCell (dev, name) {
      return cells.hasOwnProperty(name) ?
        cells[name] :
        cells[name] = _wbCellObject(dev, name);
    }
    return new Proxy(_wbDevObject(name), {
      get: function (dev, name) {
        var cell = ensureCell(dev, name);
        if (_WbRules.requireCompleteCells && !cell.isComplete())
          throw new _WbRules.IncompleteCellCaught(name);
        return cell.value().v;
      },
      set: function (dev, name, value) {
        ensureCell(dev, name).setValue({ v: value });
      }
    });
  },

  parseCellRef: function parseCellRef (cellRef) {
    var m = cellRef.match(/([^\/]+)+\/([^\/]+)+$/);
    if (!m)
      throw new Error("invalid cell reference");
    return {
      device: m[1],
      control: m[2]
    };
  },

  defineAlias: function (name, cellRef) {
    if (!name || !cellRef)
      throw new Error("invalid alias definition");
    var ref = _WbRules.parseCellRef(cellRef);
    _WbRules.aliases[name] = cellRef;
    var d = null;
    Object.defineProperty(
      (function () { return this; })(),
      name,
      {
        configurable: true,
        get: function () {
          if (!d)
            d = dev[ref.device];
          return d[ref.control];
        },
        set: function (value) {
          if (!d)
            d = dev[ref.device];
          d[ref.control] = value;
        }
      });
  },

  defineRule: function (name, def) {
    debug("defineRule: " + name);
    if (typeof name != "string" || typeof def != "object")
      throw new Error("invalid rule definition");

    function wrapConditionFunc (f, incompleteValue) {
      var conv = typeof incompleteValue == "boolean" ?
            function (v) { return !!v; } : function (v) { return v; };
      return function () {
        _WbRules.requireCompleteCells++;
        try {
          return conv(f.apply(d, arguments));
        } catch (e) {
          if (e instanceof _WbRules.IncompleteCellCaught) {
            debug("skipping rule due to incomplete cell " + name + ": " + e);
            return incompleteValue;
          }
          throw e;
        } finally {
          _WbRules.requireCompleteCells--;
        }
      };
    }

    var d = Object.create(def);
    function transformWhenChangedItem (item) {
      if (typeof item == "string") {
        if (item.indexOf("/") >= 0)
          return item;
        if (!_WbRules.aliases.hasOwnProperty(item))
          throw new Error("invalid cell alias in whenChanged: " + item);
        return _WbRules.aliases[item];
      }
      if (typeof item != "function")
        throw new Error("invalid whenChanged spec");
      return wrapConditionFunc(item, undefined);
    }

    // when: cron("...") is converted to cron: "..."
    if (def.hasOwnProperty("when") && def.when instanceof _WbRules.CronEntry) {
      def._cron = def.when.spec;
      delete def.when;
    }

    Object.keys(def).forEach(function (k) {
      var orig = d[k];
      switch(k) {
      case "readonly":
        d[k] = !!d[k]; // avoid type cast error on the Go side
        break;
      case "asSoonAs":
      case "when":
        d[k] = wrapConditionFunc(orig, false);
        break;
      case "whenChanged":
        if (Array.isArray(orig))
          d[k] = orig.map(transformWhenChangedItem);
        else
          d[k] = transformWhenChangedItem(orig);
        break;
      case "then":
        d[k] = function (options) {
          if (options) {
            if (options.hasOwnProperty("device"))
              // TBD: pass options.oldValue right after newValue here -- for consistency
              orig.call(d, options.newValue, options.device, options.cell);
            else
              orig.call(d, options.newValue);
          } else
            orig.call(d);
        };
      }
    });
    _wbDefineRule(name, d);
  },

  startTimer: function startTimer(name, ms, periodic) {
    debug("starting timer: " + name);
    _wbStartTimer(name, ms, !!periodic);
  }
};

var dev = _WbRules.autoload({}, _WbRules.wrapDevice);
var timers = _WbRules.autoload(_WbRules.timers, function (name) {
  return {
    get firing() {
      return _wbCheckCurrentTimer(name);
    },
    stop: function () {
      _wbStopTimer(name);
    }
  };
});

var defineRule = _WbRules.defineRule;

function startTimer (name, ms) {
  _WbRules.startTimer(name, ms, false);
}

function startTicker (name, ms) {
  _WbRules.startTimer(name, ms, true);
}

function setTimeout(callback, ms) {
  return _wbStartTimer(callback, ms, false);
}

function setInterval(callback, ms) {
  return _wbStartTimer(callback, ms, true);
}

function clearTimeout(id) {
  _wbStopTimer(id);
}

function clearInterval(id) {
  clearTimeout(id);
}

function spawn(cmd, args, options) {
  if (typeof options == "function")
    options = {
      exitCallback: options,
      captureOutput: false,
      captureErrorOutput: false
    };
  else if (!options)
    options = {
      exitCallback: null,
      captureOutput: false,
      captureErrorOutput: false
    };
  else {
    if (!options.hasOwnProperty("captureOutput"))
      options.captureOutput = false;
    if (!options.hasOwnProperty("captureErrorOutput"))
      options.captureErrorOutput = false;
  }

  if (options.input != null)
    options.input = "" + options.input;

  _wbSpawn([cmd].concat(args || []), options.exitCallback ? function (args) {
    try {
      options.exitCallback(
        args.exitStatus,
        options.captureOutput ? args.capturedOutput : null,
        args.capturedErrorOutput
      );
    } catch (e) {
      log("error running command callback for " + cmd + ": " + (e.stack || e));
    }
  } : null, !!options.captureOutput, !!options.captureErrorOutput, options.input);
}

function runShellCommand(cmd, options) {
  spawn("/bin/sh", ["-c", cmd], options);
}

var defineAlias = _WbRules.defineAlias;

String.prototype.format = function () {
  var args = [ this ];
  for (var i = 0; i < arguments.length; ++i)
    args.push(arguments[i]);
  return format.apply(null, args);
};

function cron(spec) {
  return new _WbRules.CronEntry(spec);
}

var Notify = (function (){
  var _smsQueue = [],
      _smsBusy = false;

  function _advanceSmsQueue () {
    if (!_smsQueue.length)
      return;
    var next = _smsQueue.shift();
    next();
  }

  return {
    sendEmail: function sendEmail (to, subject, text) {
      debug("sending email to {}: {}", to, subject);
      runShellCommand("/usr/sbin/sendmail '{}'".format(to), {
        captureErrorOutput: true,
        captureOutput: true,
        input: "Subject: {}\n\n{}".format(subject, text),
        exitCallback: function exitCallback (exitCode, capturedOutput, capturedErrorOutput) {
          if (exitCode != 0)
            log.error("error sending email to {}:\n{}\n{}", to, capturedOutput, capturedErrorOutput);
        }
      });
    },

    sendSMS: function sendSMS (to, text) {
      var doSend = function () {
        _smsBusy = true;
        debug("sending sms to {}: {}", to, text);
        runShellCommand("wb-gsm restart_if_broken && gammu sendsms TEXT '{}' -unicode".format(to), {
          captureErrorOutput: true,
          captureOutput: true,
          input: text,
          exitCallback: function (exitCode, capturedOutput, capturedErrorOutput) {
            _smsBusy = false;
            if (exitCode != 0)
              log.error("error sending sms to {}:\n{}\n{}", to, capturedOutput, capturedErrorOutput);
            _advanceSmsQueue();
          }
        });
      };

      if (_smsBusy) {
        debug("queueing sms to {}: {}", to, text);
        _smsQueue.push(doSend);
      } else
        doSend();
    }
  };
})();

var Alarms = (function () {
  var recipientTypes = {
    email: function getEmailSendFunc (src) {
      if (!src.hasOwnProperty("to"))
        throw new Error("email recipient without 'to'");
      var subject = src.hasOwnProperty("subject") ? "" + src.subject : "{}";
      return function sendEmailWrapper (text) {
        Notify.sendEmail(src.to, maybeFormat(subject, text), text);
      };
    },

    sms: function getSMSSendFunc (src) {
      if (!src.hasOwnProperty("to"))
        throw new Error("sms recipient without 'to'");
      return function sendSMSWrapper (text) {
        Notify.sendSMS(src.to, text);
      };
    }
  };

  function maybeFormat(text, arg) {
    return text.indexOf("{}") >= 0 ? text.format(arg) : text;
  }

  function getSendFunc (src) {
    if (!src || typeof src != "object" || !src.hasOwnProperty("type") ||
        !recipientTypes.hasOwnProperty(src.type))
      throw new Error("invalid recipient spec: %s", JSON.stringify(src));
    return recipientTypes[src.type](src);
  }

  var seq = 1;

  function loadAlarm (alarmSrc, notify, alarmDeviceName) {
    if (!alarmSrc || typeof alarmSrc != "object" || !alarmSrc.hasOwnProperty("cell"))
      throw new Error("invalid alarm definition");

    function checkHasNumKey (key) {
      if (!alarmSrc.hasOwnProperty(key))
        return false;

      if (typeof alarmSrc[key] != "number")
        throw new Error("{}: {}: number expected!".format(JSON.stringify(alarmSrc), key));

      return true;
    }

    var ref = _WbRules.parseCellRef(alarmSrc.cell);
    var namePrefix = "__alarm{}__{}__".format(seq++, alarmSrc.cell),
        cellName = alarmSrc.hasOwnProperty("name") ? "alarm_" + alarmSrc.name : namePrefix + "cell",
        hasExpectedValue = alarmSrc.hasOwnProperty("expectedValue"),
        hasMinValue = checkHasNumKey("minValue"),
        hasMaxValue = checkHasNumKey("maxValue"),
        alarmMessage = alarmSrc.alarmMessage ||
          alarmSrc.cell + (hasExpectedValue ? " has unexpected value = {}" : "is out of bounds, value = {}"),
        noAlarmMessage = alarmSrc.noAlarmMessage ||
          alarmSrc.cell + " is back to normal, value = {}",
        maxCount = checkHasNumKey("maxCount") ? Math.floor(alarmSrc.maxCount) : null,
        min, max, interval = null;

    if (hasExpectedValue) {
        if (hasMinValue || hasMaxValue)
          throw new Error("{}: cannot have both expectedValue and minValue/maxValue"
                          .format(JSON.stringify(alarmSrc)));
    } else {
      if (!hasMinValue && !hasMaxValue)
        throw new Error("{}: must specify either expectedValue or value range"
                        .format(JSON.stringify(alarmSrc)));
      min = hasMinValue ? alarmSrc.minValue : -Infinity;
      max = hasMaxValue ? alarmSrc.maxValue : Infinity;
    }

    if (alarmSrc.hasOwnProperty("interval")) {
      // !(alarmSrc.interval > 0) covers NaN case
      if (typeof alarmSrc.interval != "number" || !(alarmSrc.interval > 0))
        throw new Error("invalid alarm interval");
      interval = alarmSrc.interval * 1000;
    }

    var d = null;
    function cellValue () {
      if (d === null)
        d = dev[ref.device];
      return d[ref.control];
    }

    function setAlarmActiveCell(active) {
      active = !!active;
      if (dev[alarmDeviceName][cellName] !== active)
        dev[alarmDeviceName][cellName] = active;
    }

    var wasActive = false, intervalId = null, remainingCount = null;

    function stopRepeating() {
      if (intervalId != null) {
        clearInterval(intervalId);
        intervalId = null;
      }
    }

    function notifyAboutActiveAlarm() {
      if (remainingCount === null || remainingCount > 0)
        notify(maybeFormat(alarmMessage, cellValue()));
      if (remainingCount !== null && --remainingCount <= 0)
        stopRepeating();
    }

    return {
      cellName: cellName,
      defineRules: function () {
        defineRule(namePrefix + "activate", {
          asSoonAs: hasExpectedValue ? function () {
            // log("cv={}; ev={}", JSON.stringify(cellValue()), JSON.stringify(alarmSrc.expectedValue));
            return cellValue() != alarmSrc.expectedValue;
          } : function () {
            // log("cv={}; min={}, max={}", JSON.stringify(cellValue()), min, max);
            return cellValue() < min || cellValue() > max;
          },
          then: function () {
            if (wasActive)
              return;

            setAlarmActiveCell(true);

            wasActive = true;
            remainingCount = maxCount;

            notifyAboutActiveAlarm();

            if (interval !== null)
              intervalId = setInterval(notifyAboutActiveAlarm, interval);
          }
        });

        defineRule(namePrefix + "deactivate", {
          asSoonAs: hasExpectedValue ? function () {
            return cellValue() == alarmSrc.expectedValue;
          } : function () {
            return cellValue() >= min && cellValue() <= max;
          },
          then: function () {
            // Set 'alarm active' cell to false during the
            // first rule run, too. This will clear any
            // alarms remaining from before wb-rules startup /
            // loading of this rule file.
            setAlarmActiveCell(false);

            if (!wasActive)
              return;

            wasActive = false;
            stopRepeating();

            notify(maybeFormat(noAlarmMessage, cellValue()));
          }
        });
      }
    };
  }

  function doLoad (src) {
    if (!src.hasOwnProperty("deviceName"))
      throw new Error("deviceName not specified for alarms");

    if (!src.hasOwnProperty("recipients") || !Array.isArray(src.recipients) || !src.recipients.length)
      throw new Error("no (proper) recipients specified for alarms");

    if (!src.hasOwnProperty("alarms") || !Array.isArray(src.alarms) || !src.alarms.length)
      throw new Error("no (proper) alarms specified for alarms");

    var sendFuncs = src.recipients.map(getSendFunc);
    function notify (text) {
      dev[src.deviceName].log = text;
      sendFuncs.forEach(function (sendFunc) { sendFunc.call(null, text); });
    }

    var loadedAlarms = src.alarms.map(function (alarmSrc) {
      return loadAlarm(alarmSrc, notify, src.deviceName);
    });

    var deviceDef = {
      cells: {
        log: {
          type: "text",
          value: "",
          readonly: true
        }
      }
    };
    if (src.hasOwnProperty("deviceTitle"))
      deviceDef.title = src.deviceTitle;

    loadedAlarms.forEach(function (alarm) {
      deviceDef.cells[alarm.cellName] = {
        type: "alarm",
        value: false,
        readonly: true
      };
    });

    defineVirtualDevice(src.deviceName, deviceDef);

    loadedAlarms.forEach(function (alarm) {
      alarm.defineRules();
    });
  }

  return {
    load: function (src) {
      return doLoad(typeof src == "string" ? readConfig(src) : src);
    }
  };
})();
<commit_msg>Fix alarm-related diagnostic msgs.<commit_after>// rule engine runtime
var _WbRules = {
  requireCompleteCells: 0,
  timers: {},
  aliases: {},

  CronEntry: function (spec) {
    if (typeof spec != "string")
      throw new Error("invalid cron spec");
    this.spec = spec;
  },

  IncompleteCellCaught: (function () {
    function IncompleteCellCaught(cellName) {
      this.name = "IncompleteCellCaught";
      this.message = "incomplete cell encountered: " + cellName;
    }
    IncompleteCellCaught.prototype = Object.create(Error.prototype);
    return IncompleteCellCaught;
  })(),

  autoload: function (target, acquire, setValue) {
    return new Proxy(target, {
      get: function (o, name) {
        if (!(name in o)) {
          o[name] = acquire(name, o);
        }
        return o[name];
      },
      set: function (o, name, value) {
        throw new Error("setting unsupported proxy value: " + name);
      }
    });
  },

  wrapDevice: function (name) {
    var cells = {};
    function ensureCell (dev, name) {
      return cells.hasOwnProperty(name) ?
        cells[name] :
        cells[name] = _wbCellObject(dev, name);
    }
    return new Proxy(_wbDevObject(name), {
      get: function (dev, name) {
        var cell = ensureCell(dev, name);
        if (_WbRules.requireCompleteCells && !cell.isComplete())
          throw new _WbRules.IncompleteCellCaught(name);
        return cell.value().v;
      },
      set: function (dev, name, value) {
        ensureCell(dev, name).setValue({ v: value });
      }
    });
  },

  parseCellRef: function parseCellRef (cellRef) {
    var m = cellRef.match(/([^\/]+)+\/([^\/]+)+$/);
    if (!m)
      throw new Error("invalid cell reference");
    return {
      device: m[1],
      control: m[2]
    };
  },

  defineAlias: function (name, cellRef) {
    if (!name || !cellRef)
      throw new Error("invalid alias definition");
    var ref = _WbRules.parseCellRef(cellRef);
    _WbRules.aliases[name] = cellRef;
    var d = null;
    Object.defineProperty(
      (function () { return this; })(),
      name,
      {
        configurable: true,
        get: function () {
          if (!d)
            d = dev[ref.device];
          return d[ref.control];
        },
        set: function (value) {
          if (!d)
            d = dev[ref.device];
          d[ref.control] = value;
        }
      });
  },

  defineRule: function (name, def) {
    debug("defineRule: " + name);
    if (typeof name != "string" || typeof def != "object")
      throw new Error("invalid rule definition");

    function wrapConditionFunc (f, incompleteValue) {
      var conv = typeof incompleteValue == "boolean" ?
            function (v) { return !!v; } : function (v) { return v; };
      return function () {
        _WbRules.requireCompleteCells++;
        try {
          return conv(f.apply(d, arguments));
        } catch (e) {
          if (e instanceof _WbRules.IncompleteCellCaught) {
            debug("skipping rule due to incomplete cell " + name + ": " + e);
            return incompleteValue;
          }
          throw e;
        } finally {
          _WbRules.requireCompleteCells--;
        }
      };
    }

    var d = Object.create(def);
    function transformWhenChangedItem (item) {
      if (typeof item == "string") {
        if (item.indexOf("/") >= 0)
          return item;
        if (!_WbRules.aliases.hasOwnProperty(item))
          throw new Error("invalid cell alias in whenChanged: " + item);
        return _WbRules.aliases[item];
      }
      if (typeof item != "function")
        throw new Error("invalid whenChanged spec");
      return wrapConditionFunc(item, undefined);
    }

    // when: cron("...") is converted to cron: "..."
    if (def.hasOwnProperty("when") && def.when instanceof _WbRules.CronEntry) {
      def._cron = def.when.spec;
      delete def.when;
    }

    Object.keys(def).forEach(function (k) {
      var orig = d[k];
      switch(k) {
      case "readonly":
        d[k] = !!d[k]; // avoid type cast error on the Go side
        break;
      case "asSoonAs":
      case "when":
        d[k] = wrapConditionFunc(orig, false);
        break;
      case "whenChanged":
        if (Array.isArray(orig))
          d[k] = orig.map(transformWhenChangedItem);
        else
          d[k] = transformWhenChangedItem(orig);
        break;
      case "then":
        d[k] = function (options) {
          if (options) {
            if (options.hasOwnProperty("device"))
              // TBD: pass options.oldValue right after newValue here -- for consistency
              orig.call(d, options.newValue, options.device, options.cell);
            else
              orig.call(d, options.newValue);
          } else
            orig.call(d);
        };
      }
    });
    _wbDefineRule(name, d);
  },

  startTimer: function startTimer(name, ms, periodic) {
    debug("starting timer: " + name);
    _wbStartTimer(name, ms, !!periodic);
  }
};

var dev = _WbRules.autoload({}, _WbRules.wrapDevice);
var timers = _WbRules.autoload(_WbRules.timers, function (name) {
  return {
    get firing() {
      return _wbCheckCurrentTimer(name);
    },
    stop: function () {
      _wbStopTimer(name);
    }
  };
});

var defineRule = _WbRules.defineRule;

function startTimer (name, ms) {
  _WbRules.startTimer(name, ms, false);
}

function startTicker (name, ms) {
  _WbRules.startTimer(name, ms, true);
}

function setTimeout(callback, ms) {
  return _wbStartTimer(callback, ms, false);
}

function setInterval(callback, ms) {
  return _wbStartTimer(callback, ms, true);
}

function clearTimeout(id) {
  _wbStopTimer(id);
}

function clearInterval(id) {
  clearTimeout(id);
}

function spawn(cmd, args, options) {
  if (typeof options == "function")
    options = {
      exitCallback: options,
      captureOutput: false,
      captureErrorOutput: false
    };
  else if (!options)
    options = {
      exitCallback: null,
      captureOutput: false,
      captureErrorOutput: false
    };
  else {
    if (!options.hasOwnProperty("captureOutput"))
      options.captureOutput = false;
    if (!options.hasOwnProperty("captureErrorOutput"))
      options.captureErrorOutput = false;
  }

  if (options.input != null)
    options.input = "" + options.input;

  _wbSpawn([cmd].concat(args || []), options.exitCallback ? function (args) {
    try {
      options.exitCallback(
        args.exitStatus,
        options.captureOutput ? args.capturedOutput : null,
        args.capturedErrorOutput
      );
    } catch (e) {
      log("error running command callback for " + cmd + ": " + (e.stack || e));
    }
  } : null, !!options.captureOutput, !!options.captureErrorOutput, options.input);
}

function runShellCommand(cmd, options) {
  spawn("/bin/sh", ["-c", cmd], options);
}

var defineAlias = _WbRules.defineAlias;

String.prototype.format = function () {
  var args = [ this ];
  for (var i = 0; i < arguments.length; ++i)
    args.push(arguments[i]);
  return format.apply(null, args);
};

function cron(spec) {
  return new _WbRules.CronEntry(spec);
}

var Notify = (function (){
  var _smsQueue = [],
      _smsBusy = false;

  function _advanceSmsQueue () {
    if (!_smsQueue.length)
      return;
    var next = _smsQueue.shift();
    next();
  }

  return {
    sendEmail: function sendEmail (to, subject, text) {
      log("sending email to {}: {}", to, subject);
      runShellCommand("/usr/sbin/sendmail '{}'".format(to), {
        captureErrorOutput: true,
        captureOutput: true,
        input: "Subject: {}\n\n{}".format(subject, text),
        exitCallback: function exitCallback (exitCode, capturedOutput, capturedErrorOutput) {
          if (exitCode != 0)
            log.error("error sending email to {}:\n{}\n{}", to, capturedOutput, capturedErrorOutput);
        }
      });
    },

    sendSMS: function sendSMS (to, text) {
      var doSend = function () {
        _smsBusy = true;
        log("sending sms to {}: {}", to, text);
        runShellCommand("wb-gsm restart_if_broken && gammu sendsms TEXT '{}' -unicode".format(to), {
          captureErrorOutput: true,
          captureOutput: true,
          input: text,
          exitCallback: function (exitCode, capturedOutput, capturedErrorOutput) {
            _smsBusy = false;
            if (exitCode != 0)
              log.error("error sending sms to {}:\n{}\n{}", to, capturedOutput, capturedErrorOutput);
            _advanceSmsQueue();
          }
        });
      };

      if (_smsBusy) {
        debug("queueing sms to {}: {}", to, text);
        _smsQueue.push(doSend);
      } else
        doSend();
    }
  };
})();

var Alarms = (function () {
  var recipientTypes = {
    email: function getEmailSendFunc (src) {
      if (!src.hasOwnProperty("to"))
        throw new Error("email recipient without 'to'");
      var subject = src.hasOwnProperty("subject") ? "" + src.subject : "{}";
      return function sendEmailWrapper (text) {
        Notify.sendEmail(src.to, maybeFormat(subject, text), text);
      };
    },

    sms: function getSMSSendFunc (src) {
      if (!src.hasOwnProperty("to"))
        throw new Error("sms recipient without 'to'");
      return function sendSMSWrapper (text) {
        Notify.sendSMS(src.to, text);
      };
    }
  };

  function maybeFormat(text, arg) {
    return text.indexOf("{}") >= 0 ? text.format(arg) : text;
  }

  function getSendFunc (src) {
    if (!src || typeof src != "object" || !src.hasOwnProperty("type") ||
        !recipientTypes.hasOwnProperty(src.type))
      throw new Error("invalid recipient spec: %s", JSON.stringify(src));
    return recipientTypes[src.type](src);
  }

  var seq = 1;

  function loadAlarm (alarmSrc, notify, alarmDeviceName) {
    if (!alarmSrc || typeof alarmSrc != "object" || !alarmSrc.hasOwnProperty("cell"))
      throw new Error("invalid alarm definition");

    function checkHasNumKey (key) {
      if (!alarmSrc.hasOwnProperty(key))
        return false;

      if (typeof alarmSrc[key] != "number")
        throw new Error("{}: {}: number expected!".format(JSON.stringify(alarmSrc), key));

      return true;
    }

    var ref = _WbRules.parseCellRef(alarmSrc.cell);
    var namePrefix = "__alarm{}__{}__".format(seq++, alarmSrc.cell),
        cellName = alarmSrc.hasOwnProperty("name") ? "alarm_" + alarmSrc.name : namePrefix + "cell",
        hasExpectedValue = alarmSrc.hasOwnProperty("expectedValue"),
        hasMinValue = checkHasNumKey("minValue"),
        hasMaxValue = checkHasNumKey("maxValue"),
        alarmMessage = alarmSrc.alarmMessage ||
          alarmSrc.cell + (hasExpectedValue ? " has unexpected value = {}" : " is out of bounds, value = {}"),
        noAlarmMessage = alarmSrc.noAlarmMessage ||
          alarmSrc.cell + " is back to normal, value = {}",
        maxCount = checkHasNumKey("maxCount") ? Math.floor(alarmSrc.maxCount) : null,
        min, max, interval = null;

    if (hasExpectedValue) {
        if (hasMinValue || hasMaxValue)
          throw new Error("{}: cannot have both expectedValue and minValue/maxValue"
                          .format(JSON.stringify(alarmSrc)));
    } else {
      if (!hasMinValue && !hasMaxValue)
        throw new Error("{}: must specify either expectedValue or value range"
                        .format(JSON.stringify(alarmSrc)));
      min = hasMinValue ? alarmSrc.minValue : -Infinity;
      max = hasMaxValue ? alarmSrc.maxValue : Infinity;
    }

    if (alarmSrc.hasOwnProperty("interval")) {
      // !(alarmSrc.interval > 0) covers NaN case
      if (typeof alarmSrc.interval != "number" || !(alarmSrc.interval > 0))
        throw new Error("invalid alarm interval");
      interval = alarmSrc.interval * 1000;
    }

    var d = null;
    function cellValue () {
      if (d === null)
        d = dev[ref.device];
      return d[ref.control];
    }

    function setAlarmActiveCell(active) {
      active = !!active;
      if (dev[alarmDeviceName][cellName] !== active)
        dev[alarmDeviceName][cellName] = active;
    }

    var wasActive = false, intervalId = null, remainingCount = null;

    function stopRepeating() {
      if (intervalId != null) {
        clearInterval(intervalId);
        intervalId = null;
      }
    }

    function notifyAboutActiveAlarm() {
      if (remainingCount === null || remainingCount > 0)
        notify(maybeFormat(alarmMessage, cellValue()));
      if (remainingCount !== null && --remainingCount <= 0)
        stopRepeating();
    }

    return {
      cellName: cellName,
      defineRules: function () {
        defineRule(namePrefix + "activate", {
          asSoonAs: hasExpectedValue ? function () {
            // log("cv={}; ev={}", JSON.stringify(cellValue()), JSON.stringify(alarmSrc.expectedValue));
            return cellValue() != alarmSrc.expectedValue;
          } : function () {
            // log("cv={}; min={}, max={}", JSON.stringify(cellValue()), min, max);
            return cellValue() < min || cellValue() > max;
          },
          then: function () {
            if (wasActive)
              return;

            setAlarmActiveCell(true);

            wasActive = true;
            remainingCount = maxCount;

            notifyAboutActiveAlarm();

            if (interval !== null)
              intervalId = setInterval(notifyAboutActiveAlarm, interval);
          }
        });

        defineRule(namePrefix + "deactivate", {
          asSoonAs: hasExpectedValue ? function () {
            return cellValue() == alarmSrc.expectedValue;
          } : function () {
            return cellValue() >= min && cellValue() <= max;
          },
          then: function () {
            // Set 'alarm active' cell to false during the
            // first rule run, too. This will clear any
            // alarms remaining from before wb-rules startup /
            // loading of this rule file.
            setAlarmActiveCell(false);

            if (!wasActive)
              return;

            wasActive = false;
            stopRepeating();

            notify(maybeFormat(noAlarmMessage, cellValue()));
          }
        });
      }
    };
  }

  function doLoad (src) {
    if (!src.hasOwnProperty("deviceName"))
      throw new Error("deviceName not specified for alarms");

    if (!src.hasOwnProperty("recipients") || !Array.isArray(src.recipients))
      throw new Error("absent/invalid recipients spec specified for alarms");

    if (!src.hasOwnProperty("alarms") || !Array.isArray(src.alarms))
      throw new Error("absent/invalid alarms spec");

    var sendFuncs = src.recipients.map(getSendFunc);
    function notify (text) {
      dev[src.deviceName].log = text;
      sendFuncs.forEach(function (sendFunc) { sendFunc.call(null, text); });
    }

    var loadedAlarms = src.alarms.map(function (alarmSrc) {
      return loadAlarm(alarmSrc, notify, src.deviceName);
    });

    var deviceDef = {
      cells: {
        log: {
          type: "text",
          value: "",
          readonly: true
        }
      }
    };
    if (src.hasOwnProperty("deviceTitle"))
      deviceDef.title = src.deviceTitle;

    loadedAlarms.forEach(function (alarm) {
      deviceDef.cells[alarm.cellName] = {
        type: "alarm",
        value: false,
        readonly: true
      };
    });

    defineVirtualDevice(src.deviceName, deviceDef);

    loadedAlarms.forEach(function (alarm) {
      alarm.defineRules();
    });
  }

  return {
    load: function (src) {
      return doLoad(typeof src == "string" ? readConfig(src) : src);
    }
  };
})();
<|endoftext|>


<commit_before>var context;
window.addEventListener('load', init, false);
function init() {
	var dogBarkingUrl = 'https://upload.wikimedia.org/wikipedia/commons/c/ce/Sound-of-dog.ogg';
	var dogBarkingBuffer = null;
	// Fix up prefixing
	window.AudioContext = window.AudioContext || window.webkitAudioContext;
	context = new AudioContext();

	loadDogSound(dogBarkingUrl);
	alert('Sound Loaded');
	playSound(dogBarkingBuffer);
}

function loadDogSound(url) {
	var request = new XMLHttpRequest();
	request.open('GET', url, true);
	request.responseType = 'arraybuffer';

	// Decode asynchronously
	request.onload = function() {
		context.decodeAudioData(
			request.response,
			playSound,
			function(e){"Error with decoding audio data" + e.err}
		);
	}
	request.send();
}

function playSound(buffer) {
  var source = context.createBufferSource(); // creates a sound source
  source.buffer = buffer;                    // tell the source which sound to play
  source.connect(context.destination);       // connect the source to the context's destination (the speakers)
  source.start(0);                           // play the source now
                                             // note: on older systems, may have to use deprecated noteOn(time);
}
<commit_msg>Try `noteOn` method<commit_after>var context;
window.addEventListener('load', init, false);
function init() {
	var dogBarkingUrl = 'https://upload.wikimedia.org/wikipedia/commons/c/ce/Sound-of-dog.ogg';
	var dogBarkingBuffer = null;
	// Fix up prefixing
	window.AudioContext = window.AudioContext || window.webkitAudioContext;
	context = new AudioContext();

	loadDogSound(dogBarkingUrl);
	alert('Sound Loaded');
	playSound(dogBarkingBuffer);
}

function loadDogSound(url) {
	var request = new XMLHttpRequest();
	request.open('GET', url, true);
	request.responseType = 'arraybuffer';

	// Decode asynchronously
	request.onload = function() {
		context.decodeAudioData(
			request.response,
			playSound,
			function(e){"Error with decoding audio data" + e.err}
		);
	}
	request.send();
}

function playSound(buffer) {
	var source = context.createBufferSource(); // creates a sound source
	source.buffer = buffer;                    // tell the source which sound to play
	source.connect(context.destination);       // connect the source to the context's destination (the speakers)
	source.start(0);                           // play the source now
//	source.noteOn(0);						   // note: on older systems, may have to use deprecated noteOn(time);
}
<|endoftext|>


<commit_before>var context;
window.addEventListener('load', init, false);
function init() {
	try {
	  var dogBarkingUrl = 'https://upload.wikimedia.org/wikipedia/commons/c/ce/Sound-of-dog.ogg';
		var dogBarkingBuffer = null;
		// Fix up prefixing
		window.AudioContext = window.AudioContext || window.webkitAudioContext;
		context = new AudioContext();

		loadDogSound(dogBarkingUrl);
		alert('Sound Loaded');
		playSound(dogBarkingBuffer);
	}
	catch(e) {
		alert('Web Audio API is not supported in this browser');
	}
}

function loadDogSound(url) {
	var request = new XMLHttpRequest();
	request.open('GET', url, true);
	request.responseType = 'arraybuffer';

	// Decode asynchronously
	request.onload = function() {
		context.decodeAudioData(
			request.response,
			playSound,
			function(e){"Error with decoding audio data" + e.err});
		);
	}
	request.send();
}

function playSound(buffer) {
  var source = context.createBufferSource(); // creates a sound source
  source.buffer = buffer;                    // tell the source which sound to play
  source.connect(context.destination);       // connect the source to the context's destination (the speakers)
  source.start(0);                           // play the source now
                                             // note: on older systems, may have to use deprecated noteOn(time);
}
<commit_msg>Fix uncaught syntax error<commit_after>var context;
window.addEventListener('load', init, false);
function init() {
	try {
	  var dogBarkingUrl = 'https://upload.wikimedia.org/wikipedia/commons/c/ce/Sound-of-dog.ogg';
		var dogBarkingBuffer = null;
		// Fix up prefixing
		window.AudioContext = window.AudioContext || window.webkitAudioContext;
		context = new AudioContext();

		loadDogSound(dogBarkingUrl);
		alert('Sound Loaded');
		playSound(dogBarkingBuffer);
	}
	catch(e) {
		alert('Web Audio API is not supported in this browser');
	}
}

function loadDogSound(url) {
	var request = new XMLHttpRequest();
	request.open('GET', url, true);
	request.responseType = 'arraybuffer';

	// Decode asynchronously
	request.onload = function() {
		context.decodeAudioData(
			request.response,
			playSound,
			function(e){"Error with decoding audio data" + e.err}
		);
	}
	request.send();
}

function playSound(buffer) {
  var source = context.createBufferSource(); // creates a sound source
  source.buffer = buffer;                    // tell the source which sound to play
  source.connect(context.destination);       // connect the source to the context's destination (the speakers)
  source.start(0);                           // play the source now
                                             // note: on older systems, may have to use deprecated noteOn(time);
}
<|endoftext|>


<commit_before>§(function(){
  'use strict';

  var moj = {

    Modules: {},

    Helpers: {},

    Events: $({}),

    init: function () {
      for (var x in moj.Modules) {
        if (typeof moj.Modules[x].init === 'function') {
          moj.Modules[x].init();
        }
      }
      // trigger initial render event
      moj.Events.trigger('render');
    },

    // safe logging
    log: function (msg) {
      if (window && window.console) {
        window.console.log(msg);
      }
    },
    dir: function (obj) {
      if (window && window.console) {
        window.console.dir(obj);
      }
    }

  };

  window.moj = moj;
}());

(function () {
  'use strict';

  // Invite interested developers to join us
  moj.Modules.devs = {
    init: function () {
      var m = '     ___          ___       ___\n     /__/\\        /  /\\     /  /\\\n    |  |::\\      /  /::\\   /  /:/\n    |  |:|:\\    /  /:/\\:\\ /__/::\\\n  __|__|:|\\:\\  /  /:/  \\:\\\\__\\/\\:\\\n /__/::::| \\:\\/__/:/ \\__\\:\\  \\  \\:\\\n \\  \\:\\~~\\__\\/\\  \\:\\ /  /:/   \\__\\:\\\n  \\  \\:\\       \\  \\:\\  /:/    /  /:/\n   \\  \\:\\       \\  \\:\\/:/    /__/:/\n    \\  \\:\\       \\  \\::/     \\__\\/\n     \\__\\/        \\__\\/',
      txt = '\n\nLike what you see? Want to make a difference?'+
            '\n\nFind out how we\'re making the Ministry Of Justice Digital by Default.'+
            '\nhttps://mojdigital.blog.gov.uk/.'+
            '\n\nGet in touch to see what positions are available and see what projects you could be working on.'+
            '\nhttps://mojdigital.blog.gov.uk/working-at-moj-ds/';
      moj.log(m+txt);
    }
  };
}());
<commit_msg>Update moj.js<commit_after>$(function(){
  'use strict';

  var moj = {

    Modules: {},

    Helpers: {},

    Events: $({}),

    init: function () {
      for (var x in moj.Modules) {
        if (typeof moj.Modules[x].init === 'function') {
          moj.Modules[x].init();
        }
      }
      // trigger initial render event
      moj.Events.trigger('render');
    },

    // safe logging
    log: function (msg) {
      if (window && window.console) {
        window.console.log(msg);
      }
    },
    dir: function (obj) {
      if (window && window.console) {
        window.console.dir(obj);
      }
    }

  };

  window.moj = moj;
}());

(function () {
  'use strict';

  // Invite interested developers to join us
  moj.Modules.devs = {
    init: function () {
      var m = '     ___          ___       ___\n     /__/\\        /  /\\     /  /\\\n    |  |::\\      /  /::\\   /  /:/\n    |  |:|:\\    /  /:/\\:\\ /__/::\\\n  __|__|:|\\:\\  /  /:/  \\:\\\\__\\/\\:\\\n /__/::::| \\:\\/__/:/ \\__\\:\\  \\  \\:\\\n \\  \\:\\~~\\__\\/\\  \\:\\ /  /:/   \\__\\:\\\n  \\  \\:\\       \\  \\:\\  /:/    /  /:/\n   \\  \\:\\       \\  \\:\\/:/    /__/:/\n    \\  \\:\\       \\  \\::/     \\__\\/\n     \\__\\/        \\__\\/',
      txt = '\n\nLike what you see? Want to make a difference?'+
            '\n\nFind out how we\'re making the Ministry Of Justice Digital by Default.'+
            '\nhttps://mojdigital.blog.gov.uk/.'+
            '\n\nGet in touch to see what positions are available and see what projects you could be working on.'+
            '\nhttps://mojdigital.blog.gov.uk/working-at-moj-ds/';
      moj.log(m+txt);
    }
  };
}());
<|endoftext|>


<commit_before>$(function() {

    function log( message ) {
        $( "<div>" ).text( message ).prependTo( "#log" );
        $( "#log" ).scrollTop( 0 );
    }

    $("#emp").autocomplete({
        source: function(request, response) {
            $.ajax({
                url: "http://reclameimovel.com.br/api/empreendimento",
                dataType: "jsonp",
                data: {
                    featureClass: "P",
                },
                success: function(data) {
                    response(data);
                }
            });
        },
        minLength: 2,
        select: function(event, ui) {
            log(ui);
        },
        open: function() {
            $(this).removeClass("ui-corner-all").addClass("ui-corner-top");
        },
        close: function() {
            $(this).removeClass("ui-corner-top").addClass("ui-corner-all");
        }
    });

});
<commit_msg>Autocomplete<commit_after>$(function() {

    function log( message ) {
        $( "<div>" ).text( message ).prependTo( "#log" );
        $( "#log" ).scrollTop( 0 );
    }

    $("#emp").autocomplete({
        source: function(request, response) {
            $.ajax({
                url: "http://reclameimovel.com.br/api/empreendimento",
                dataType: "jsonp",
                data: {
                    featureClass: "P",
                },
                success: function(data) {
                    console.log(data);

                    response(data);
                }
            });
        },
        minLength: 2,
        select: function(event, ui) {
            console.log(event);
            console.log(ui);
        },
        open: function() {
            $(this).removeClass("ui-corner-all").addClass("ui-corner-top");
        },
        close: function() {
            $(this).removeClass("ui-corner-top").addClass("ui-corner-all");
        }
    });

});
<|endoftext|>


<commit_before>'use strict';

app.directive('authApplyForm', [
  'pageService', function (page) {
    var link = function ($scope) {
      var party = $scope.party || page.models.Login.user;
      var auth = $scope.auth;
      var form = $scope.authApplyForm;

      form.data = {};

      if (auth.new)
        form.$setDirty();

      //

      var saveAuth = function () {
        form.$setSubmitted();
        party.authorizeApply(auth.party.id, form.data).then(function () {
          form.$setUnsubmitted();
          form.validator.server({});
          form.$setPristine();
          delete auth.new;

          form.successFn(auth);
        }, function (res) {
          form.validator.server(res);
          page.display.scrollTo(form.$element);
        });
      };

      var saveQuery = function () {
        page.messages.clear(form);
        party.authorizeNotFound(angular.extend({
          name: auth.query
        }, form.data)).then(function () {
          form.validator.server({});
          form.$setPristine();
          delete auth.new;

          form.successFn(auth);
        }, function (res) {
          form.validator.server(res);
          page.display.scrollTo(form.$element);
        });
      };

      form.save = function () {
        if (auth.party)
          saveAuth();
        else
          saveQuery();
      };

      //

      form.cancel = function () {
        form.cancelFn(auth);
      };

      //

      form.validator.client({}, true);

      //

      $scope.$emit('authApplyForm-init', form);
    };

    //

    return {
      restrict: 'E',
      templateUrl: 'party/authApply.html',
      scope: false,
      replace: true,
      link: link
    };
  }
]);
<commit_msg>Add obviously missing setUnsubmitted in authApply error case<commit_after>'use strict';

app.directive('authApplyForm', [
  'pageService', function (page) {
    var link = function ($scope) {
      var party = $scope.party || page.models.Login.user;
      var auth = $scope.auth;
      var form = $scope.authApplyForm;

      form.data = {};

      if (auth.new)
        form.$setDirty();

      //

      var saveAuth = function () {
        form.$setSubmitted();
        party.authorizeApply(auth.party.id, form.data).then(function () {
          form.$setUnsubmitted();
          form.validator.server({});
          form.$setPristine();
          delete auth.new;

          form.successFn(auth);
        }, function (res) {
          form.$setUnsubmitted();
          form.validator.server(res);
          page.display.scrollTo(form.$element);
        });
      };

      var saveQuery = function () {
        page.messages.clear(form);
        party.authorizeNotFound(angular.extend({
          name: auth.query
        }, form.data)).then(function () {
          form.validator.server({});
          form.$setPristine();
          delete auth.new;

          form.successFn(auth);
        }, function (res) {
          form.validator.server(res);
          page.display.scrollTo(form.$element);
        });
      };

      form.save = function () {
        if (auth.party)
          saveAuth();
        else
          saveQuery();
      };

      //

      form.cancel = function () {
        form.cancelFn(auth);
      };

      //

      form.validator.client({}, true);

      //

      $scope.$emit('authApplyForm-init', form);
    };

    //

    return {
      restrict: 'E',
      templateUrl: 'party/authApply.html',
      scope: false,
      replace: true,
      link: link
    };
  }
]);
<|endoftext|>


<commit_before>/**
* input 图片上传
* 功能点：分段上传
*/
(function (window) {
	//默认配置
	var options = {
		ids:null,
		start:function(){},//开始上传
		process:function(){},//每一次上传成功后实时回调，返回当前进度
		success:function(){},//上传成功
		error:function(){},//上传失败
		type:1,//上传类型  1普通上传  2 私密上传
		uploadUrl:"http://101.201.76.184:8999",
		blockSize:10*1024,
		base64:''
	},
	interfaces = {
		vldUrl:"/authUploadFile",
		url:"/binaryStreamUpload"
	};

	var startFunc = [],processFunc = [],successFunc = [],errorFunc = []

	//API
	var api = {
		init: function(opts){
			if(opts){
				for(var key in opts) {
					options[key] = opts[key];
				}
			}
			if(options.ids && options.ids.length > 0){
				for(var i=0;i<options.ids.length;i++){
					var id = options.ids[i];
					startFunc[id] = options.start;
					processFunc[id] = options.process;
					successFunc[id] = options.success;
					errorFunc[id] = options.error;
					dobind(id);
				}

			}

			return this;
		}
	}

	var dobind = function(id){
		var ele = document.getElementById(id);
		ele.onchange = function(){
			if(ele.files){
				var file = ele.files[0];
				if(file.type.indexOf('image/')>-1){
					wang(file);
					validate(id,file);
				}else if(file && file.type.indexOf('image/')==-1){
					if(ele.getAttribute("upld")){
						errorFunc[id]({"status":false,"id":id,"message":"正在上传中，客官莫急！"});
					}else{
						validate(id,file);
					}
				}
			}else{
				errorFunc[id]({"status":false,"id":id,"message":"浏览器版本过低，请升级"});
			}

		}
	}

	var wang = function(fileObj){

	 	var file = fileObj,
            cvs = document.createElement("canvas"),
            ctx = cvs.getContext("2d");
        if(file){
            var url = window.URL.createObjectURL(file);//PS:不兼容IE
            var img = new Image();
            img.src = url;
            img.onload = function(){
                ctx.clearRect(0,0,cvs.width,cvs.height);

                cvs.width = 500;
                cvs.height = 500 * (img.height / img.width);
                drawImageIOSFix(ctx,img,0,0,img.width,img.height,0,0,cvs.width,cvs.height);
				var base64 = cvs.toDataURL("image/png",0.1);
                var image_base64 = base64.replace('data:image/png;base64,','');
                options.base64 = image_base64;
            }
        }
	}

	function detectVerticalSquash(img) {
		var iw = img.naturalWidth, ih = img.naturalHeight;
		var canvas = document.createElement('canvas');
		canvas.width = 1;
		canvas.height = ih;
		var ctx = canvas.getContext('2d');
		ctx.drawImage(img, 0, 0);
		var data = ctx.getImageData(0, 0, 1, ih).data;
		// search image edge pixel position in case it is squashed vertically.
		var sy = 0;
		var ey = ih;
		var py = ih;
		while (py > sy) {
			var alpha = data[(py - 1) * 4 + 3];
			if (alpha === 0) {
				ey = py;
			} else {
				sy = py;
			}
			py = (ey + sy) >> 1;
		}
		var ratio = (py / ih);
		return (ratio===0)?1:ratio;
	}
	function drawImageIOSFix(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {
		var vertSquashRatio = detectVerticalSquash(img);
		ctx.drawImage(img, sx * vertSquashRatio, sy * vertSquashRatio,
				sw * vertSquashRatio, sh * vertSquashRatio,
				dx, dy, dw, dh);
	}

	//验证 上传
	var validate = function(id,file){
		var total = 1;
		try{
			total =  1;//Math.ceil(file.size/options.blockSize);
		}catch(e){}
		startFunc[id]();
		setTimeout(function(){
			ajax({
				url: options.uploadUrl + interfaces.vldUrl,
				dataType: 'json',
				type: 'POST',
				data: {
					"total":total,
					"name":file.name,
					"size":file.size,
					"type":file.type
				},
				success: function (data) {
					if (data.success) {
						if(options.base64){
							upload1(id,options.base64,data.uid,total);
						}else{
							upload(id,file,data.uid,total);
						}

					}else{
						errorFunc[id]({"status":false,"id":id,"message":"验证失败"});
						clearInput(id);
					}

				},
				error: function (data) {
					errorFunc[id]({"status":false,"id":id,"message":"验证失败"});
					clearInput(id);
				}
			});
		},1000)

	}

	//上传
	var upload = function(id,file,uid,total){
		var ele = document.getElementById(id);
		ele.setAttribute("upld","1");
		var breakFlag = false;
		var per = options.blockSize;
		for(var i=0;i<total;i++){
			var perFile;
			if(i < total-1){
				perFile = file.slice(i*per,(i+1)*per);
			}else{
				perFile = file.slice(i*per,file.size);
			}
			var fmData = new FormData();
			fmData.append("type", 1);
			fmData.append("uid", uid);
			fmData.append("num", 1);
			fmData.append("imgStr", file);
			ajax({
				url: options.uploadUrl + interfaces.url,
				dataType: 'json',
				contentType: false,
				type: 'POST',
				async:false,
				data:fmData,
				success: function (data) {
					if (data.success){
						processFunc[id]({"id":id,"percent":(i+1)/total});
						if(i+1 == total){
							var result = {"id":id,"url":data.idata};
							successFunc[id](result);
							clearInput(id);
						}

					}else{
						breakFlag = true;
						errorFunc[id]({"status":false,"id":id,"message":"上传失败"});
						clearInput(id);
					}

				},
				error: function (o, xhr, property) {
					breakFlag = true;
					errorFunc[id]({"status":false,"id":id,"message":"上传失败"});
					clearInput(id);
				}
			});
			if(breakFlag){
				break;
			}

		}

	}

	var upload1 = function(id,file,uid,total){
		var ele = document.getElementById(id);
		ele.setAttribute("upld","1");
		var breakFlag = false;
		var per = options.blockSize;
		for(var i=0;i<total;i++){
			var perFile;
			if(i < total-1){
				perFile = file.slice(i*per,(i+1)*per);
			}else{
				perFile = file.slice(i*per,file.size);
			}
			ajax({
				url: options.uploadUrl + '/upload',
				dataType: 'json',
				type: 'POST',
				async:false,
				data:{
					'uid':uid,
					'type':1,
					'num':1,
					'imgStr':encodeURIComponent(file)
				},
				success: function (data) {
					if (data.success){
						processFunc[id]({"id":id,"percent":(i+1)/total});
						if(i+1 == total){
							var result = {"id":id,"url":data.idata};
							successFunc[id](result);
							clearInput(id);
						}

					}else{
						breakFlag = true;
						errorFunc[id]({"status":false,"id":id,"message":"上传失败"});
						clearInput(id);
					}

				},
				error: function (o, xhr, property) {
					breakFlag = true;
					errorFunc[id]({"status":false,"id":id,"message":"上传失败"});
					clearInput(id);
				}
			});
			if(breakFlag){
				break;
			}

		}

	}

	//重置input属性
	var clearInput = function(id){
		var ele = document.getElementById(id);
		if(ele.getAttribute("upld")){
			ele.removeAttribute("upld");
		}
		ele.value = "";
	}

	//封装ajax
	function ajax(obj) {
		if (window.XMLHttpRequest) {//IE7+、Firefox、Opera、Chrome 和Safari
			 var xhr = new XMLHttpRequest();
		} else if (window.ActiveXObject) {   //IE6 及以下
			var xhr = new ActiveXObject("Microsoft.XMLHTTP");
		} else {
			alert('浏览器版本过低！');
			return;
		}
		//obj.url = obj.url + '?rand=' + Math.random();
		if (obj.type === 'get' || obj.type === 'GET') {
			obj.url += obj.url.indexOf('?') == -1 ? '?' + obj.data : '&' + obj.data;
		}
		if (obj.async !== false) {//异步
			xhr.onreadystatechange = function () {
				if (xhr.readyState == 4) {
					callback();
				}
			};
		}
		xhr.open(obj.type, obj.url, obj.async);
		if (obj.type === 'post' || obj.type === 'POST') {
			if(obj.contentType !== false){
				obj.data = convertData(obj.data);
				xhr.setRequestHeader('Content-Type', "application/x-www-form-urlencoded");
			}

			try{
				xhr.send(obj.data);
			}catch(e){
				obj.error({"success":false,"message":"接口faile"});
			}
		} else {
			try{
				xhr.send(null);		//get方式则填null
			}catch(e){
				obj.error({"success":false,"message":"接口failed"});
			}
		}
		if (obj.async === false) {//同步
			callback();
		}
		function callback() {
			if (xhr.status == 200) {
				var resultData = xhr.responseText;
				if(obj.dataType == "json" && typeof resultData !== "object"){
					resultData = JSON.parse(resultData);
				}
				obj.success(resultData);
			} else {
				obj.error({"success":false,"message":"接口failed"});
			}
		}
	}

	function convertData(data){
	  if( typeof data === 'object' ){
		var convertResult = "" ;
		for(var c in data){
		  convertResult+= c + "=" + data[c] + "&";
		}
		convertResult=convertResult.substring(0,convertResult.length-1)
		return convertResult;
	  }else{
		return data;
	  }
	}

	this.xvUpload = api;

})(window);<commit_msg>shangchuan<commit_after>/**
* input 图片上传
* 功能点：分段上传
*/
(function (window) {
	//默认配置
	var options = {
		ids:null,
		start:function(){},//开始上传
		process:function(){},//每一次上传成功后实时回调，返回当前进度
		success:function(){},//上传成功
		error:function(){},//上传失败
		type:1,//上传类型  1普通上传  2 私密上传
		uploadUrl:"http://101.201.76.184:8999",
		blockSize:10*1024,
		base64:''
	},
	interfaces = {
		vldUrl:"/authUploadFile",
		url:"/binaryStreamUpload"
	};

	var startFunc = [],processFunc = [],successFunc = [],errorFunc = []

	//API
	var api = {
		init: function(opts){
			if(opts){
				for(var key in opts) {
					options[key] = opts[key];
				}
			}
			if(options.ids && options.ids.length > 0){
				for(var i=0;i<options.ids.length;i++){
					var id = options.ids[i];
					startFunc[id] = options.start;
					processFunc[id] = options.process;
					successFunc[id] = options.success;
					errorFunc[id] = options.error;
					dobind(id);
				}

			}

			return this;
		}
	}

	var dobind = function(id){
		var ele = document.getElementById(id);
		ele.onchange = function(){
			if(ele.files){
				var file = ele.files[0];
				if(file.type.indexOf('image/')>-1){
					wang(file);
					validate(id,file);
				}else if(file && file.type.indexOf('image/')==-1){
					if(ele.getAttribute("upld")){
						errorFunc[id]({"status":false,"id":id,"message":"正在上传中，客官莫急！"});
					}else{
						validate(id,file);
					}
				}
			}else{
				errorFunc[id]({"status":false,"id":id,"message":"浏览器版本过低，请升级"});
			}

		}
	}

	var wang = function(fileObj){

	 	var file = fileObj,
            cvs = document.createElement("canvas"),
            ctx = cvs.getContext("2d");
        if(file){
            var url = window.URL.createObjectURL(file);//PS:不兼容IE
            var img = new Image();
            img.src = url;
            img.onload = function(){
                ctx.clearRect(0,0,cvs.width,cvs.height);

                cvs.width = 500;
                cvs.height = 500 * (img.height / img.width);
                drawImageIOSFix(ctx,img,0,0,img.width,img.height,0,0,cvs.width,cvs.height);
				var base64 = cvs.toDataURL("image/png",0.1);
                var image_base64 = base64.replace('data:image/png;base64,','');
                options.base64 = image_base64;
            }
        }
	}

	function detectVerticalSquash(img) {
		var iw = img.naturalWidth, ih = img.naturalHeight;
		var canvas = document.createElement('canvas');
		canvas.width = 1;
		canvas.height = ih;
		var ctx = canvas.getContext('2d');
		ctx.drawImage(img, 0, 0);
		var data = ctx.getImageData(0, 0, 1, ih).data;
		// search image edge pixel position in case it is squashed vertically.
		var sy = 0;
		var ey = ih;
		var py = ih;
		while (py > sy) {
			var alpha = data[(py - 1) * 4 + 3];
			if (alpha === 0) {
				ey = py;
			} else {
				sy = py;
			}
			py = (ey + sy) >> 1;
		}
		var ratio = (py / ih);
		return (ratio===0)?1:ratio;
	}
	function drawImageIOSFix(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {
		var vertSquashRatio = detectVerticalSquash(img);
		ctx.drawImage(img, sx * vertSquashRatio, sy * vertSquashRatio,
				sw * vertSquashRatio, sh * vertSquashRatio,
				dx, dy, dw, dh);
	}

	//验证 上传
	var validate = function(id,file){
		var total = 1;
		try{
			total =  1;//Math.ceil(file.size/options.blockSize);
		}catch(e){}
		startFunc[id]();
		console.log(file)
		setTimeout(function(){
			ajax({
				url: options.uploadUrl + interfaces.vldUrl,
				dataType: 'json',
				type: 'POST',
				data: {
					"total":total,
					"name":'1.'+file.type.split('/')[1],
					"size":file.size,
					"type":file.type
				},
				success: function (data) {
					if (data.success) {
						if(options.base64){
							upload1(id,options.base64,data.uid,total);
						}else{
							upload(id,file,data.uid,total);
						}

					}else{
						errorFunc[id]({"status":false,"id":id,"message":"验证失败"});
						clearInput(id);
					}

				},
				error: function (data) {
					errorFunc[id]({"status":false,"id":id,"message":"验证失败"});
					clearInput(id);
				}
			});
		},1000)

	}

	//上传
	var upload = function(id,file,uid,total){
		var ele = document.getElementById(id);
		ele.setAttribute("upld","1");
		var breakFlag = false;
		var per = options.blockSize;
		for(var i=0;i<total;i++){
			var perFile;
			if(i < total-1){
				perFile = file.slice(i*per,(i+1)*per);
			}else{
				perFile = file.slice(i*per,file.size);
			}
			var fmData = new FormData();
			fmData.append("type", 1);
			fmData.append("uid", uid);
			fmData.append("num", 1);
			fmData.append("imgStr", file);
			ajax({
				url: options.uploadUrl + interfaces.url,
				dataType: 'json',
				contentType: false,
				type: 'POST',
				async:false,
				data:fmData,
				success: function (data) {
					if (data.success){
						processFunc[id]({"id":id,"percent":(i+1)/total});
						if(i+1 == total){
							var result = {"id":id,"url":data.idata};
							successFunc[id](result);
							clearInput(id);
						}

					}else{
						breakFlag = true;
						errorFunc[id]({"status":false,"id":id,"message":"上传失败"});
						clearInput(id);
					}

				},
				error: function (o, xhr, property) {
					breakFlag = true;
					errorFunc[id]({"status":false,"id":id,"message":"上传失败"});
					clearInput(id);
				}
			});
			if(breakFlag){
				break;
			}

		}

	}

	var upload1 = function(id,file,uid,total){
		var ele = document.getElementById(id);
		ele.setAttribute("upld","1");
		var breakFlag = false;
		var per = options.blockSize;
		for(var i=0;i<total;i++){
			var perFile;
			if(i < total-1){
				perFile = file.slice(i*per,(i+1)*per);
			}else{
				perFile = file.slice(i*per,file.size);
			}
			ajax({
				url: options.uploadUrl + '/upload',
				dataType: 'json',
				type: 'POST',
				async:false,
				data:{
					'uid':uid,
					'type':1,
					'num':1,
					'imgStr':encodeURIComponent(file)
				},
				success: function (data) {
					if (data.success){
						processFunc[id]({"id":id,"percent":(i+1)/total});
						if(i+1 == total){
							var result = {"id":id,"url":data.idata};
							successFunc[id](result);
							clearInput(id);
						}

					}else{
						breakFlag = true;
						errorFunc[id]({"status":false,"id":id,"message":"上传失败"});
						clearInput(id);
					}

				},
				error: function (o, xhr, property) {
					breakFlag = true;
					errorFunc[id]({"status":false,"id":id,"message":"上传失败"});
					clearInput(id);
				}
			});
			if(breakFlag){
				break;
			}

		}

	}

	//重置input属性
	var clearInput = function(id){
		var ele = document.getElementById(id);
		if(ele.getAttribute("upld")){
			ele.removeAttribute("upld");
		}
		ele.value = "";
	}

	//封装ajax
	function ajax(obj) {
		if (window.XMLHttpRequest) {//IE7+、Firefox、Opera、Chrome 和Safari
			 var xhr = new XMLHttpRequest();
		} else if (window.ActiveXObject) {   //IE6 及以下
			var xhr = new ActiveXObject("Microsoft.XMLHTTP");
		} else {
			alert('浏览器版本过低！');
			return;
		}
		//obj.url = obj.url + '?rand=' + Math.random();
		if (obj.type === 'get' || obj.type === 'GET') {
			obj.url += obj.url.indexOf('?') == -1 ? '?' + obj.data : '&' + obj.data;
		}
		if (obj.async !== false) {//异步
			xhr.onreadystatechange = function () {
				if (xhr.readyState == 4) {
					callback();
				}
			};
		}
		xhr.open(obj.type, obj.url, obj.async);
		if (obj.type === 'post' || obj.type === 'POST') {
			if(obj.contentType !== false){
				obj.data = convertData(obj.data);
				xhr.setRequestHeader('Content-Type', "application/x-www-form-urlencoded");
			}

			try{
				xhr.send(obj.data);
			}catch(e){
				obj.error({"success":false,"message":"接口faile"});
			}
		} else {
			try{
				xhr.send(null);		//get方式则填null
			}catch(e){
				obj.error({"success":false,"message":"接口failed"});
			}
		}
		if (obj.async === false) {//同步
			callback();
		}
		function callback() {
			if (xhr.status == 200) {
				var resultData = xhr.responseText;
				if(obj.dataType == "json" && typeof resultData !== "object"){
					resultData = JSON.parse(resultData);
				}
				obj.success(resultData);
			} else {
				obj.error({"success":false,"message":"接口failed"});
			}
		}
	}

	function convertData(data){
	  if( typeof data === 'object' ){
		var convertResult = "" ;
		for(var c in data){
		  convertResult+= c + "=" + data[c] + "&";
		}
		convertResult=convertResult.substring(0,convertResult.length-1)
		return convertResult;
	  }else{
		return data;
	  }
	}

	this.xvUpload = api;

})(window);<|endoftext|>


<commit_before>'use strict';

/* global _, $, PNotify, angular, moment, pouchdb, md5, uuid, marked, CartConst, CartUtility */
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- LIB & ANNOUNCEMENT
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// underscore
global._ = require('underscore');

// jQuery family
global.$ = global.jQuery = require('jquery');
require('./../bower/jquery-ui/ui/jquery-ui.js');
require('./../bower/letteringjs/jquery.lettering.js');
require('./../bower/textillate/jquery.textillate.js');
require('./../bower/bootstrap/dist/js/bootstrap.js');
require('./../bower/fullcalendar/fullcalendar.js');
require('./../bower/pnotify/pnotify.core.js'); // PNotify core
require('./../bower/pnotify/pnotify.buttons.js'); // PNotify buttons

// angular family
require('angular');
require('angular-route');
require('angular-animate');
require('angular-route-segment');
require('angular-cookies');
require('angular-ui-calendar');
require('angular-file-upload');
require('angular-ui-utils');
require('angular-bootstrap');
require('angular-contenteditable');

// others
global.moment = require('moment');
global.PouchDB = require('pouchdb');
global.md5 = require('blueimp-md5').md5;
global.uuid = require('./../bower/node-uuid/uuid.js');
global.marked = require('./../bower/marked/index.js');

// app sources
global.CartConst = require('./const/const.js');
var routerSource = require('./router/router.js');
var ctrlSources = require('./controller/controllers.js');
var serviceSources = require('./service/services.js');

// app utility
global.CartUtility = require('./utility.js');

//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- APP
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
var app = angular.module('Cart', [
    'ngRoute', 'ngAnimate', 'ngCookies',
    'route-segment', 'view-segment',
    'angularFileUpload', 'ui.calendar', 'ui.utils', 'contenteditable', 'ui.bootstrap',
    'Cart.Controllers', 'Cart.Services'
]);

//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- ROUTE
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
app.config(['$routeProvider', '$locationProvider', '$routeSegmentProvider', routerSource]);

//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- CONTROLLER
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
var controllers = angular.module('Cart.Controllers', []);

controllers.controller('CartMainCtrl', ['$scope', '$location', '$cookies', '$window', '$routeSegment', 'CartFixFooterService', 'CartDataService', 'CartAccessCtrlService', ctrlSources.CartMainCtrl]);
controllers.controller('CartBlogListCtrl', ['$scope', '$location', '$window', '$routeParams', '$modal', 'CartDataService', 'CartAccessCtrlService', ctrlSources.CartBlogListCtrl]);
controllers.controller('CartBlogListModalCtrl', ['$scope', '$location', '$modalInstance', 'CartDataService', ctrlSources.CartBlogListModalCtrl]);
controllers.controller('CartBlogEditCtrl', ['$scope', '$location', '$anchorScroll', '$routeParams', 'CartDataService', 'FileUploader', ctrlSources.CartBlogEditCtrl]);
controllers.controller('CartBlogViewCtrl', ['$scope', '$location', '$window', '$routeParams', '$anchorScroll', 'CartAccessCtrlService', 'CartDataService', ctrlSources.CartBlogViewCtrl]);
controllers.controller('CartBlogCategoryCtrl', ['$scope', ctrlSources.CartBlogCategoryCtrl]);
controllers.controller('CartBlogTagCtrl', ['$scope', ctrlSources.CartBlogTagCtrl]);
controllers.controller('CartSearchCtrl', ['$scope', '$compile', ctrlSources.CartSearchCtrl]);
controllers.controller('CartOauthCtrl', ['$scope', '$location', '$window', 'CartAccessCtrlService', ctrlSources.CartOauthCtrl]);
controllers.controller('CartLoginCtrl', ['$scope', '$window', 'CartAccessCtrlService', ctrlSources.CartLoginCtrl]);
controllers.controller('CartProfileCtrl', ['$scope', ctrlSources.CartProfileCtrl]);
controllers.controller('CartMasterCtrl', ['$scope', ctrlSources.CartMasterCtrl]);

//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- SERVICE
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
var services = angular.module('Cart.Services', []);

services.factory('CartAccessCtrlService', ['$http', '$q', '$cookies', serviceSources.CartAccessCtrlService]);
services.factory('CartDataService', ['$http', '$q', serviceSources.CartDataService]);
services.factory('CartFixFooterService', [function() {
    return { 'fixFooter': fixFooter };
}]);

//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- BOOTSTRAP
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
var $html = angular.element(document.getElementsByTagName('html')[0]);
angular.element().ready(function() {
    // boot angular
    angular.bootstrap($html, ['Cart']);

    // nav hover display effect
    $('.page-content').mousemove(_.throttle(function(e) {
        var elementOffset = $(this).offset();
        var posX = e.pageX - elementOffset.left;
        var posY = e.pageY - elementOffset.top;
        if (posX <= CartConst.NAV_TRIGGER_HINT_X && posY <= CartConst.NAV_TRIGGER_HINT_Y) {
            $('.nav-trigger').addClass('nav-trigger-active');
        } else {
            $('.nav-trigger').removeClass('nav-trigger-active');
        }
    }, 150)); // do mouse move event every 150ms

    // window resize event
    $(window).resize(_.throttle(fixFooter, 150)); // do fixFooter every 150ms

    // scroll to top
    var toTopBtn = $('.page-to-top');
    $(window).scroll(function() {
        if ($(this).scrollTop() > 300) {
            toTopBtn.fadeIn(500);
        } else {
            toTopBtn.fadeOut(500);
        }
    });
    toTopBtn.click(function(event) {
        event.preventDefault();
        $('html, body').animate({ scrollTop: 0 }, 500);
        return false;
    });
});

//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- OTHERS
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
var fixFooter = function() {
    var pageContentTop = $('.page-content-top'); // page top element: page content excepts footer
    var pageTopCurHeight = pageContentTop.height(); // current page top height
    var pageTopMinHeight = $(document).height() - CartConst.PAGE_FOOTER_HEIGHT; // min page top height
    if (pageTopCurHeight < pageTopMinHeight) {
        // only fix the footer position when page is too 'short'
        pageContentTop.css('min-height', pageTopMinHeight);
    }
};

//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- MARKED
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
var renderer = new marked.Renderer();
renderer.heading = function(text, level) { // add anchor link
    return '' +
        '<h' + level + '>' +
        '' +
        text +
        '</h' + level + '>';
};
marked.setOptions({
    renderer: renderer,
    gfm: true,
    tables: true,
    breaks: true,
    pedantic: false,
    sanitize: true,
    smartLists: true,
    smartypants: false,
    highlight: function (code, lang) {
        // since the highlight class name added with highlight lib itself not working, have to wrap code tag by self
        return '' + hljs.highlightAuto(code, [lang]).value + '';
    }
});<commit_msg>Fix global comment for js lint.<commit_after>'use strict';

/* global _, $, PNotify, angular, moment, hljs, pouchdb, md5, uuid, marked, CartConst, CartUtility */
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- LIB & ANNOUNCEMENT
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// underscore
global._ = require('underscore');

// jQuery family
global.$ = global.jQuery = require('jquery');
require('./../bower/jquery-ui/ui/jquery-ui.js');
require('./../bower/letteringjs/jquery.lettering.js');
require('./../bower/textillate/jquery.textillate.js');
require('./../bower/bootstrap/dist/js/bootstrap.js');
require('./../bower/fullcalendar/fullcalendar.js');
require('./../bower/pnotify/pnotify.core.js'); // PNotify core
require('./../bower/pnotify/pnotify.buttons.js'); // PNotify buttons

// angular family
require('angular');
require('angular-route');
require('angular-animate');
require('angular-route-segment');
require('angular-cookies');
require('angular-ui-calendar');
require('angular-file-upload');
require('angular-ui-utils');
require('angular-bootstrap');
require('angular-contenteditable');

// others
global.moment = require('moment');
global.PouchDB = require('pouchdb');
global.md5 = require('blueimp-md5').md5;
global.uuid = require('./../bower/node-uuid/uuid.js');
global.marked = require('./../bower/marked/index.js');

// app sources
global.CartConst = require('./const/const.js');
var routerSource = require('./router/router.js');
var ctrlSources = require('./controller/controllers.js');
var serviceSources = require('./service/services.js');

// app utility
global.CartUtility = require('./utility.js');

//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- APP
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
var app = angular.module('Cart', [
    'ngRoute', 'ngAnimate', 'ngCookies',
    'route-segment', 'view-segment',
    'angularFileUpload', 'ui.calendar', 'ui.utils', 'contenteditable', 'ui.bootstrap',
    'Cart.Controllers', 'Cart.Services'
]);

//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- ROUTE
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
app.config(['$routeProvider', '$locationProvider', '$routeSegmentProvider', routerSource]);

//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- CONTROLLER
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
var controllers = angular.module('Cart.Controllers', []);

controllers.controller('CartMainCtrl', ['$scope', '$location', '$cookies', '$window', '$routeSegment', 'CartFixFooterService', 'CartDataService', 'CartAccessCtrlService', ctrlSources.CartMainCtrl]);
controllers.controller('CartBlogListCtrl', ['$scope', '$location', '$window', '$routeParams', '$modal', 'CartDataService', 'CartAccessCtrlService', ctrlSources.CartBlogListCtrl]);
controllers.controller('CartBlogListModalCtrl', ['$scope', '$location', '$modalInstance', 'CartDataService', ctrlSources.CartBlogListModalCtrl]);
controllers.controller('CartBlogEditCtrl', ['$scope', '$location', '$anchorScroll', '$routeParams', 'CartDataService', 'FileUploader', ctrlSources.CartBlogEditCtrl]);
controllers.controller('CartBlogViewCtrl', ['$scope', '$location', '$window', '$routeParams', '$anchorScroll', 'CartAccessCtrlService', 'CartDataService', ctrlSources.CartBlogViewCtrl]);
controllers.controller('CartBlogCategoryCtrl', ['$scope', ctrlSources.CartBlogCategoryCtrl]);
controllers.controller('CartBlogTagCtrl', ['$scope', ctrlSources.CartBlogTagCtrl]);
controllers.controller('CartSearchCtrl', ['$scope', '$compile', ctrlSources.CartSearchCtrl]);
controllers.controller('CartOauthCtrl', ['$scope', '$location', '$window', 'CartAccessCtrlService', ctrlSources.CartOauthCtrl]);
controllers.controller('CartLoginCtrl', ['$scope', '$window', 'CartAccessCtrlService', ctrlSources.CartLoginCtrl]);
controllers.controller('CartProfileCtrl', ['$scope', ctrlSources.CartProfileCtrl]);
controllers.controller('CartMasterCtrl', ['$scope', ctrlSources.CartMasterCtrl]);

//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- SERVICE
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
var services = angular.module('Cart.Services', []);

services.factory('CartAccessCtrlService', ['$http', '$q', '$cookies', serviceSources.CartAccessCtrlService]);
services.factory('CartDataService', ['$http', '$q', serviceSources.CartDataService]);
services.factory('CartFixFooterService', [function() {
    return { 'fixFooter': fixFooter };
}]);

//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- BOOTSTRAP
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
var $html = angular.element(document.getElementsByTagName('html')[0]);
angular.element().ready(function() {
    // boot angular
    angular.bootstrap($html, ['Cart']);

    // nav hover display effect
    $('.page-content').mousemove(_.throttle(function(e) {
        var elementOffset = $(this).offset();
        var posX = e.pageX - elementOffset.left;
        var posY = e.pageY - elementOffset.top;
        if (posX <= CartConst.NAV_TRIGGER_HINT_X && posY <= CartConst.NAV_TRIGGER_HINT_Y) {
            $('.nav-trigger').addClass('nav-trigger-active');
        } else {
            $('.nav-trigger').removeClass('nav-trigger-active');
        }
    }, 150)); // do mouse move event every 150ms

    // window resize event
    $(window).resize(_.throttle(fixFooter, 150)); // do fixFooter every 150ms

    // scroll to top
    var toTopBtn = $('.page-to-top');
    $(window).scroll(function() {
        if ($(this).scrollTop() > 300) {
            toTopBtn.fadeIn(500);
        } else {
            toTopBtn.fadeOut(500);
        }
    });
    toTopBtn.click(function(event) {
        event.preventDefault();
        $('html, body').animate({ scrollTop: 0 }, 500);
        return false;
    });
});

//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- OTHERS
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
var fixFooter = function() {
    var pageContentTop = $('.page-content-top'); // page top element: page content excepts footer
    var pageTopCurHeight = pageContentTop.height(); // current page top height
    var pageTopMinHeight = $(document).height() - CartConst.PAGE_FOOTER_HEIGHT; // min page top height
    if (pageTopCurHeight < pageTopMinHeight) {
        // only fix the footer position when page is too 'short'
        pageContentTop.css('min-height', pageTopMinHeight);
    }
};

//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//- MARKED
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
var renderer = new marked.Renderer();
renderer.heading = function(text, level) { // add anchor link
    return '' +
        '<h' + level + '>' +
        '' +
        text +
        '</h' + level + '>';
};
marked.setOptions({
    renderer: renderer,
    gfm: true,
    tables: true,
    breaks: true,
    pedantic: false,
    sanitize: true,
    smartLists: true,
    smartypants: false,
    highlight: function (code, lang) {
        // since the highlight class name added with highlight lib itself not working, have to wrap code tag by self
        return '' + hljs.highlightAuto(code, [lang]).value + '';
    }
});<|endoftext|>