text:
CocoaLumberjack
===============
![Unit Tests](https://github.com/CocoaLumberjack/CocoaLumberjack/workflows/Unit%20Tests/badge.svg)
[![Pod Version](http://img.shields.io/cocoapods/v/CocoaLumberjack.svg?style=flat)](http://cocoadocs.org/docsets/CocoaLumberjack/)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![Pod Platform](http://img.shields.io/cocoapods/p/CocoaLumberjack.svg?style=flat)](http://cocoadocs.org/docsets/CocoaLumberjack/)
[![Pod License](http://img.shields.io/cocoapods/l/CocoaLumberjack.svg?style=flat)](http://opensource.org/licenses/BSD-3-Clause)
[![codecov](https://codecov.io/gh/CocoaLumberjack/CocoaLumberjack/branch/master/graph/badge.svg)](https://codecov.io/gh/CocoaLumberjack/CocoaLumberjack)
[![codebeat badge](https://codebeat.co/badges/840b714a-c8f3-4936-ada4-363473cd4e6b)](https://codebeat.co/projects/github-com-cocoalumberjack-cocoalumberjack-master)

**CocoaLumberjack** is a fast & simple, yet powerful & flexible logging framework for macOS, iOS, tvOS and watchOS.

## How to get started

First, install CocoaLumberjack via [CocoaPods](http://cocoapods.org), [Carthage](https://github.com/Carthage/Carthage), [Swift Package Manager](https://swift.org/package-manager/) or manually.
Then use `DDOSLogger` for iOS 10 and later, or `DDTTYLogger` and `DDASLLogger` for earlier versions to begin logging messages.

### CocoaPods

```ruby
platform :ios, '9.0'

target 'SampleTarget' do
  use_frameworks!
  pod 'CocoaLumberjack/Swift'
end
```
Note: `Swift` is a subspec which will include all the Obj-C code plus the Swift one, so this is sufficient.
For more details about how to use Swift with Lumberjack, see [this conversation](https://github.com/CocoaLumberjack/CocoaLumberjack/issues/405).

For Objective-C use the following:
```ruby
platform :ios, '9.0'

target 'SampleTarget' do
    pod 'CocoaLumberjack'
end
```

### Carthage

Carthage is a lightweight dependency manager for Swift and Objective-C. It leverages CocoaTouch modules and is less invasive than CocoaPods.

To install with Carthage, follow the instruction on [Carthage](https://github.com/Carthage/Carthage)

Cartfile
```
github "CocoaLumberjack/CocoaLumberjack"
```

### Swift Package Manager

As of CocoaLumberjack 3.6.0, you can use the Swift Package Manager as integration method.
If you want to use the Swift Package Manager as integration method, either use Xcode to add the package dependency or add the following dependency to your Package.swift:

```swift
.package(url: "https://github.com/CocoaLumberjack/CocoaLumberjack.git", from: "3.7.0"),
```

Note that you may need to add both products, `CocoaLumberjack` and `CocoaLumberjackSwift` to your target since SPM sometimes fails to detect that `CocoaLumerjackSwift` depends on `CocoaLumberjack`.

### Install manually

If you want to install CocoaLumberjack manually, read the [manual installation](https://raw.githubusercontent.com/CocoaLumberjack/CocoaLumberjack/master/Documentation/GettingStarted.md#manual-installation) guide for more information.

### Swift Usage

Usually, you can simply `import CocoaLumberjackSwift`. If you installed CocoaLumberjack using CocoaPods, you need to use `import CocoaLumberjack` instead.

```swift
DDLog.add(DDOSLogger.sharedInstance) // Uses os_log

let fileLogger: DDFileLogger = DDFileLogger() // File Logger
fileLogger.rollingFrequency = 60 * 60 * 24 // 24 hours
fileLogger.logFileManager.maximumNumberOfLogFiles = 7
DDLog.add(fileLogger)

...

DDLogVerbose("Verbose")
DDLogDebug("Debug")
DDLogInfo("Info")
DDLogWarn("Warn")
DDLogError("Error")
```

### Obj-C usage

If you're using Lumberjack as a framework, you can `@import CocoaLumberjack;`.
Otherwise, `#import <CocoaLumberjack/CocoaLumberjack.h>`

```objc
[DDLog addLogger:[DDOSLogger sharedInstance]]; // Uses os_log

DDFileLogger *fileLogger = [[DDFileLogger alloc] init]; // File Logger
fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling
fileLogger.logFileManager.maximumNumberOfLogFiles = 7;
[DDLog addLogger:fileLogger];

...

DDLogVerbose(@"Verbose");
DDLogDebug(@"Debug");
DDLogInfo(@"Info");
DDLogWarn(@"Warn");
DDLogError(@"Error");
```
### Objective-C ARC Semantic Issue

When integrating Lumberjack into an existing Objective-C it is possible to run into `Multiple methods named 'tag' found with mismatched result, parameter type or attributes` build error.

Add `#define DD_LEGACY_MESSAGE_TAG 0` before importing CocoaLumberjack or add `#define DD_LEGACY_MESSAGE_TAG 0` or add `-DDD_LEGACY_MESSAGE_TAG=0` to *Other C Flags*/*OTHER_CFLAGS* in your Xcode project.

## [swift-log](https://github.com/apple/swift-log) backend

CocoaLumberjack also ships with a backend implementation for [swift-log](https://github.com/apple/swift-log).
Simply add CocoaLumberjack as dependency to your SPM target (see above) and also add the `CocoaLumberjackSwiftLogBackend` product as dependency to your target.

You can then use `DDLogHandler` as backend for swift-log, which will forward all messages to CocoaLumberjack's `DDLog`. You will still configure the loggers and log formatters you want via `DDLog`, but writing log messages will be done using `Logger` from swift-log.

In your own log formatters, you can make use of the `swiftLogInfo` property on `DDLogMessage` to retrieve the details of a message that is logged via swift-log.

### More information

- read the [Getting started](https://raw.githubusercontent.com/CocoaLumberjack/CocoaLumberjack/master/Documentation/GettingStarted.md) guide, check out the [FAQ](https://raw.githubusercontent.com/CocoaLumberjack/CocoaLumberjack/master/Documentation/FAQ.md) section or the other [docs](Documentation/)
- if you find issues or want to suggest improvements, create an issue or a pull request
- for all kinds of questions involving CocoaLumberjack, use the [Google group](http://groups.google.com/group/cocoalumberjack) or StackOverflow (use [#lumberjack](http://stackoverflow.com/questions/tagged/lumberjack)).

## CocoaLumberjack 3

### Migrating to 3.x

* To be determined

## Features

### Lumberjack is Fast & Simple, yet Powerful & Flexible.

It is similar in concept to other popular logging frameworks such as log4j, yet is designed specifically for Objective-C, and takes advantage of features such as multi-threading, grand central dispatch (if available), lockless atomic operations, and the dynamic nature of the Objective-C runtime.

### Lumberjack is Fast

In most cases it is an order of magnitude faster than NSLog.

### Lumberjack is Simple

It takes as little as a single line of code to configure lumberjack when your application launches. Then simply replace your NSLog statements with DDLog statements and that's about it. (And the DDLog macros have the exact same format and syntax as NSLog, so it's super easy.)

### Lumberjack is Powerful:

One log statement can be sent to multiple loggers, meaning you can log to a file and the console simultaneously. Want more? Create your own loggers (it's easy) and send your log statements over the network. Or to a database or distributed file system. The sky is the limit.

### Lumberjack is Flexible:

Configure your logging however you want. Change log levels per file (perfect for debugging). Change log levels per logger (verbose console, but concise log file). Change log levels per xcode configuration (verbose debug, but concise release). Have your log statements compiled out of the release build. Customize the number of log levels for your application. Add your own fine-grained logging. Dynamically change log levels during runtime. Choose how & when you want your log files to be rolled. Upload your log files to a central server. Compress archived log files to save disk space...

## This framework is for you if:

-   You're looking for a way to track down that impossible-to-reproduce bug that keeps popping up in the field.
-   You're frustrated with the super short console log on the iPhone.
-   You're looking to take your application to the next level in terms of support and stability.
-   You're looking for an enterprise level logging solution for your application (Mac or iPhone).

## Documentation

- **[Get started using Lumberjack](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/GettingStarted.md)**

- [Different log levels for Debug and Release builds](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/XcodeTricks.md)

- [Different log levels for each logger](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/PerLoggerLogLevels.md)

- [Use colors in the Xcode debugging console](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/XcodeColors.md)

- [Write your own custom formatters](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/CustomFormatters.md)

- [FAQ](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/FAQ.md)

- [Analysis of performance with benchmarks](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/Performance.md)

- [Common issues you may encounter and their solutions](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/ProblemSolution.md)

- [AppCode support](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/AppCode-support.md)
- **[Full Lumberjack documentation](Documentation/)**

## Requirements
The current version of Lumberjack requires:
- Xcode 12 or later
- Swift 5.3 or later
- iOS 9 or later
- macOS 10.10 or later
- watchOS 3 or later
- tvOS 9 or later

### Backwards compatibility
- for Xcode 11 and Swift up to 5.2, use the 3.6.2 version
- for Xcode 10 and Swift 4.2, use the 3.5.2 version
- for iOS 8, use the 3.6.1 version
- for iOS 6, iOS 7, OS X 10.8, OS X 10.9 and Xcode 9, use the 3.4.2 version
- for iOS 5 and OS X 10.7, use the 3.3 version
- for Xcode 8 and Swift 3, use the 3.2 version
- for Xcode 7.3 and Swift 2.3, use the 2.4.0 version
- for Xcode 7.3 and Swift 2.2, use the 2.3.0 version
- for Xcode 7.2 and 7.1, use the 2.2.0 version
- for Xcode 7.0 or earlier, use the 2.1.0 version
- for Xcode 6 or earlier, use the 2.0.x version
- for OS X < 10.7 support, use the 1.6.0 version

## Communication

- If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/lumberjack). (Tag 'lumberjack')
- If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/lumberjack).
- If you **found a bug**, open an issue.
- If you **have a feature request**, open an issue.
- If you **want to contribute**, submit a pull request.

## Data Collection Practices

Per [App privacy details on the App Store](https://developer.apple.com/app-store/app-privacy-details/), Apple is requesting app developers to provide info about their data collection, us SDK maintainers must provide them with the same data.

### Data collection by the framework

**By default, CocoaLumberjack does NOT collect any data on its own.**

[See our Data Collection Practices list.](https://cocoalumberjack.github.io/DataCollection/index.html)

### Indirect data collection through the framework

CocoaLumberjack is a logging framework which makes it easy to send those logs to different platforms.

This is why collecting data might happen quite easily, if app developers include any sensitive data into their log messages.

**Important note: app developers are fully responsible for any sensitive data collected through our logging system!**

In consequence, you must comply to the Apple's privacy details policy (mentioned above) and document the ways in which user data is being collected.
Since the number of scenarios where data might be indirectly collected through CocoaLumberjack is quite large, it's up to you, as app developers, to properly review your app's code and identify those cases.
What we can do to help is raise awareness about potential data collection through our framework.

Private data includes but isn't limited to:

- user info (name, email, address, ...)
- location info
- contacts
- identifiers (user id, device id, ...)
- app usage data
- performance data
- health and fitness info
- financial info
- sensitive info
- user content
- history (browsing, search, ...)
- purchases
- diagnostics
- ...

_Example_: `DDLogInfo("User: \(myUser)")` will add the `myUser` info to the logs, so if those are forwarded to a 3rd party or sent via email, that may qualify as data collection.

## Author

- [Robbie Hanson](https://github.com/robbiehanson)
- Love the project? Wanna buy me a coffee? (or a beer :D) [![donation](http://www.paypal.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UZRA26JPJB3DA)

## Collaborators
- [Ernesto Rivera](https://github.com/rivera-ernesto)
- [Dmitry Vorobyov](https://github.com/dvor)
- [Bogdan Poplauschi](https://github.com/bpoplauschi)
- [C.W. Betts](https://github.com/MaddTheSane)
- [Koichi Yokota (sushichop)](https://github.com/sushichop)
- [Nick Brook](https://github.com/nrbrook)
- [Florian Friedrich](https://github.com/ffried)
- [Stephan Diederich](https://github.com/diederich)
- [Kent Sutherland](https://github.com/ksuther)
- [Dmitry Lobanov](https://github.com/lolgear)
- [Hakon Hanesand](https://github.com/hhanesand)

## License
- CocoaLumberjack is available under the BSD 3 license. See the [LICENSE file](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/LICENSE).

## Extensions
- [LogIO-CocoaLumberjack](https://github.com/s4nchez/LogIO-CocoaLumberjack) A log.io logger for CocoaLumberjack
- [XCDLumberjackNSLogger](https://github.com/0xced/XCDLumberjackNSLogger) CocoaLumberjack logger which sends logs to NSLogger

## Architecture


text:
***

katakan anda memiliki sebuah rumah tapi anda ingin membuat beberapa ruangan dalam rumah tersebut dengan fungsi
yang berbeda maka anda perlu mengatur ukurannya, pintu, dinding dan lainnya. layout berfungsi seperti ruangan
pada applikasi anda. anda hanya perlu menyimpan layout tersebut didalam folder `model/layout` setelah anda membuat
layout yang perlu anda lakukan adalah mendefinisikannya kedalam `Alias`

**Attention**:

     when you create your layout make sure you create your package first, for example "model/layout/welcome/" It also necessary for widget and controller.

redpajama_set_name: RedPajamaGithub


text:
require "spec_helper"

describe CookbookDeprecatedNotifier do
  let!(:system_email1) { create(:system_email, name: "Cookbook deleted") }
  let!(:system_email2) { create(:system_email, name: "Cookbook deprecated") }

  it "sends emails to cookbook owner, collaborators and followers who want to receive emails" do
    disinterested_user = create(:user)
    disinterested_user.email_preference_for("Cookbook deprecated").destroy
    cookbook = create(:cookbook)
    cookbook.deprecate(create(:cookbook).name)
    cookbook_collaborator = create(:cookbook_collaborator, resourceable: cookbook)
    cookbook_followers = [
      create(:cookbook_follower, cookbook: cookbook),
      create(
        :cookbook_follower,
        cookbook: cookbook,
        user: disinterested_user
      ),
    ]

    users_to_email = [
      cookbook.owner,
      cookbook_collaborator.user,
      cookbook_followers[0].user,
    ]

    Sidekiq::Testing.inline! do
      CookbookDeprecatedNotifier.new.perform(cookbook.id)
    end

    recipients = ActionMailer::Base.deliveries.map(&:to).flatten.sort

    expect(recipients).to eql(users_to_email.map(&:email).sort)
  end
end


text:
Parser utility for binary traces from fsp-trace driver.

## HOWTO ##
For using it you have to find proper hash file/trex string file
which is needed to associate hashs with strings.

Example:

	fsp-trace -s hash_file.trc <buffer_file>

## Building ##

	make


text:
var _includes = /*#__PURE__*/require('./internal/_includes');

var _curry2 = /*#__PURE__*/require('./internal/_curry2');

/**
 * Returns `true` if the specified value is equal, in [`R.equals`](#equals)
 * terms, to at least one element of the given list; `false` otherwise.
 * Works also with strings.
 *
 * @func
 * @memberOf R
 * @since v0.1.0
 * @category List
 * @sig a -> [a] -> Boolean
 * @param {Object} a The item to compare against.
 * @param {Array} list The array to consider.
 * @return {Boolean} `true` if an equivalent item is in the list, `false` otherwise.
 * @see R.any
 * @example
 *
 *      R.includes(3, [1, 2, 3]); //=> true
 *      R.includes(4, [1, 2, 3]); //=> false
 *      R.includes({ name: 'Fred' }, [{ name: 'Fred' }]); //=> true
 *      R.includes([42], [[42]]); //=> true
 *      R.includes('ba', 'banana'); //=>true
 */

var includes = /*#__PURE__*/_curry2(_includes);
module.exports = includes;


text:
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  TextEditor startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%..

@rem Add default JVM options here. You can also use JAVA_OPTS and TEXT_EDITOR_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windows variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\lib\TextEditor-0.1.0.jar;%APP_HOME%\lib\autocomplete-2.5.8.jar;%APP_HOME%\lib\rstaui-2.5.7.jar;%APP_HOME%\lib\rsyntaxtextarea-2.5.8.jar

@rem Execute TextEditor
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %TEXT_EDITOR_OPTS%  -classpath "%CLASSPATH%" TextEditor %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable TEXT_EDITOR_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%TEXT_EDITOR_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


text:
<?php

namespace Virtphp;

class Virtphp
{
    const VERSION = '@package_version@';
    const RELEASE_DATE = '@release_date@';

    /**
     * Make sure provided environment name is valid.
     *
     * @param string $envName The environment name to check
     * @return boolean Whether or not the provided name is valid for this system
     */
    public static function isValidName($envName)
    {
        if (preg_match("/^[a-zA-Z][0-9a-zA-Z_\-]*$/", $envName)) {
            return true;
        }

        return false;
    }
}


text:
from django.conf.urls import url

from apps.approval.dashboard import views

urlpatterns = [
    url(r'^$', views.index, name='approvals'),
    url(r'^approve_application/$', views.approve_application, name='approval_approve_application'),
    url(r'^decline_application/$', views.decline_application, name='approval_decline_application'),
]


text:
@interface CCHTransportDEBahnBhftafelParser : NSObject<CCHTransportParser>

- (NSArray *)parseResponseWithData:(NSData *)data;

@end


text:
//***********************************************************************//
//																		 //
//		- "Talk to me like I'm a 3 year old!" Programming Lessons -		 //
//                                                                       //
//		$Author:		Ben Humphrey	DigiBen@gametutorials.com		 //
//																		 //
//		$Program:		RPG (Part 2)									 //
//																		 //
//		$Description:	A basic example of a 2D RPG						 //

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

#pragma comment(lib, "Winmm.lib")				// Include this windows library for PlaySound()
#pragma comment(lib, "fmodvc.lib")				// Include the Fmod library for music

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

#include "main.h"								// Include our main header file

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

// In this second tutorial we will jump right into more game code.  We will plug in Menu code,
// moving Npcs, dialog and music and sound.  The SoundFX won't really be used until later
// tutorials, but we will at least put in the code for playing a sound when the player
// dies.  The only sounds we will use will be an item pick up sound and a death sound.
// These all can't be coded yet since we won't probably any of that until later tutorials.
// We can, however, add the cool music in the game immediately :)
//
// In this tutorial, the character can walk up to an Npc and talk to them.  This is done
// by running into them.  The user can then press the space key or escape to skip through
// the dialog.  Next, you can press escape and toggle a menu.  The menu has options for
// inventory, saving, loading and quitting, yet only the quitting option does anything.
// It.... quits :)  The next tutorial will allow for inventory menus.  You must use the
// mouse to choose options from the menu.  We create a menu and a button class.  This allows
// us to create menus with buttons.  You can assign some text to a button, and when the user
// clicks on it with the mouse, it will be directed to a function that handles the action for
// that button.  We do this by function pointers.
//
// *User input for this tutorial*
//
// Arrow Keys - Move the player
// Esc - Toggle the main menu (Or escapes a menu) and escapes/continues dialog
// Space Bar - Escapes/continues the dialog
// Left Mouse Button - This chooses the options from the main menu
//
// Play the sweet game music and let it inspire you as you check out this tutorial :)
// (Note: you do not need to look at Fmod files, as there is nothing intended to be learned
// from them.  Fmod is a music library created by FireLight Multimedia (www.Fmod.org))
//

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

CMap g_Map;										// This stores our global map object
CPlayer g_Player;								// This stores our global player object
CInput g_Input;									// This is the global input object
POINT g_cursorPos = {0};						// The current mouse cursor position
CBuffer g_Buffer;								// Create a buffer for the main window

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

CMenu g_Menu;									// This is our global menu object
CFmod g_Music;									// This is our global music object

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

HWND  g_hWnd;									// This is a global handle for the window
HINSTANCE g_hInstance;							// This holds the global hInstance for UnregisterClass() in DeInit()

////////////////////////////// HANDLE WINDOWS MESSAGES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This handles windows messages and used for when we aren't in the main loop
/////
////////////////////////////// HANDLE WINDOWS MESSAGES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

int CInput::HandleWindowsMessages()
{
	MSG msg;

	// Here we check to see if there is a message, and remove it from the queue if so
	if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
		//If we are trying to quit, post a quit message again and return -1 to tell
		// the previous function that call us to quit what ever it's doing.
		if(msg.message == WM_QUIT)
		{
			PostQuitMessage(0);
			return -1;
		}

		// Handle the messages
		TranslateMessage(&msg);
		DispatchMessage(&msg);

		// We got a message so return 1
		return 1;
	}

	// No message, return 0
	return 0;
}

///////////////////////////////// INIT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function initializes our application-specific data
/////
///////////////////////////////// INIT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void Init(HWND hWnd)
{
	// Set our global window handle to our main window
	g_hWnd = hWnd;

	// Create our double buffering our window
	g_Buffer.CreateDoubleBuffering(hWnd);

	// This is where we create the image of our character
	HBITMAP hPlayerImage = g_Buffer.LoadABitmap((LPSTR)kPlayerImage);

	// Initialize our player with it's image and position
	g_Player.Init(hPlayerImage, kPlayerStartX, kPlayerStartY);

	// Init, load and draw the first map file
	g_Map.Load(kStartMap);
	g_Map.SetDrawFlag(true);

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

	// Here we load then play the starting background music
	if(!g_Music.Init("techno.mod"))
		exit(0);

	g_Music.PlaySong();

	// we need to seed our random number generator (rand()) for moving npcs.
	srand(GetTickCount());

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

	// Set the backbuffer to black first (This clears the backbuffer)
	g_Buffer.ClearScreen(BLACK_BRUSH);
}

///////////////////////////////// MAIN GAME LOOP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function handles the main loop and calls our drawing routine
/////
///////////////////////////////// MAIN GAME LOOP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

WPARAM MainLoop()
{
	MSG msg;
	// This is where we load our accelerators for keyboard shortcuts
	HACCEL hAccelTable = LoadAccelerators(g_hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));

	while(g_Player.IsAlive())							// Loop until the player is dead
	{													// Check if there was a message
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
			if(msg.message == WM_QUIT)					// If the message was to quit
				break;

			// Check if there was keyboard command - if not, process messages like normal
			if(!TranslateAccelerator(g_hWnd, hAccelTable, &msg))
			{
				TranslateMessage(&msg);					// Find out what the message does
				DispatchMessage(&msg);					// Execute the message
			}

			// Here is where we handle the main game input
			HandleGameInput();

			// Let's draw the map when we need to draw (if the draw flag == true).
			g_Map.Draw();

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

			// Just like the g_Map.Draw() command, we will attempt to draw the menu, but it
			// will only be draw if it's draw flag is set to true.  This is the main menu.
			g_Menu.Draw();

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

			// Swap the backbuffers to display the bitmaps to the screen
			g_Buffer.SwapBackBuffer(FALSE);
		}

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

		// We want the Npcs to freely walk around so we need to move them every frame
		g_Map.MoveNpcs();
	}

	// If the player died because they were killed, let's display a death sound.
	// This of course can't be heard until we start fighting monsters :)
	if(!g_Player.IsAlive())
	{
		// We use PlaySound() to play our .wav files. We tell it
		// that we want to play the Death.wav file, and it should be
		// played from a file asynchronously.  That means that it will
		// play on a separate thread and we don't have to wait for it to
		// finish before the game continues on.  We then display a death message.
		PlaySound("Death.wav", NULL, SND_FILENAME | SND_ASYNC);
		g_Menu.DrawMessageBox("You have perished!");
		Sleep(1000);
	}

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

	// Clean up and free all allocated memory
	DeInit();

	// Return from the program
	return(msg.wParam);
}

///////////////////////////// HANDLE GAME INPUT /////////////////////////////
/////
/////	This actually handles the main game input from the user (movement, etc...)
/////
///////////////////////////// HANDLE GAME INPUT /////////////////////////////

void HandleGameInput()
{
	// Store the position of the player before we possibly move
	POINT lastPosition = g_Player.GetLastPosition();

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

	// Now that we have menu code, we can display a main menu when ESC is pressed
	if(g_Input.IsKeyDown(VK_ESCAPE))		// If escape was pressed
		g_Menu.BringUpMenu();

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

	else if(g_Input.IsKeyDown(VK_UP))		// If up arrow key was pressed
		g_Player.Move(kUp);					// Move the character up
	else if(g_Input.IsKeyDown(VK_DOWN))		// If down arrow key was pressed
		g_Player.Move(kDown);				// Move the character down
	else if(g_Input.IsKeyDown(VK_LEFT))		// If left arrow key was pressed
		g_Player.Move(kLeft);				// Move the character left
	else if(g_Input.IsKeyDown(VK_RIGHT))	// If right arrow key was pressed
		g_Player.Move(kRight);				// Move the character right

	// Store the new current position of the player
	POINT curPosition = g_Player.GetPosition();

	// Check if the player moved by testing the current position against the last position
	if(lastPosition.x != curPosition.x || lastPosition.y != curPosition.y)
	{
		// We want to draw the screen again if the character moved
		g_Map.SetDrawFlag(true);

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

			// If we run into an NPC, we need to know so we can display dialog.
			// The dialog code will be called from this function CheckForNpc().
			g_Map.CheckForNpc(curPosition.x, curPosition.y);

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

		// Set the previous position of the player
		g_Player.SetLastPosition(curPosition);

		// Here we check to see if the player moved into an exit.  If so, exit!
		g_Map.CheckForExit(curPosition.x, curPosition.y);
	}
}

///////////////////////////////// HANDLE MENU \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function processes the actions when a menu item is chosen
/////
///////////////////////////////// HANDLE MENU \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void HandleMenu(int menuID)
{
	if(menuID == ID_FILE_QUIT)					// If the user chose File->Quit
		PostQuitMessage(0);						// Quit the program
	else if(menuID == ID_FILE_OPENUP)			// If the user chose File->Open
	{
	}
	else if(menuID == ID_FILE_SAVEIT)			// If the user chose File->Save
	{
	}
	else if(menuID == ID_HELP_ABOUT)			// If the user chose Help->About
	{
		// Instead of creating a dialog box, we can just use a simple system MessageBox() call
		MessageBox(g_hWnd, "www.GameTutorials.com RPG\n\n"
						   "\t- To move the character you use the arrow keys.\n"
						   "\t- To access the main menu, hit the escape key.\n"
						   "\t- To exit from the menus hit the escape key.\n"
						   "\t- To turn on and off the status bar press space bar.\n"
						   "\t- To continue dialog, press space bar or escape.\n"
						   "\t- To use the menus use the left mouse button.", "About", MB_OK | MB_ICONINFORMATION);
	}
}

/////////////////////////////////// WND PROC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function processes the messages that come to and from our window
/////
/////////////////////////////////// WND PROC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

LRESULT CALLBACK WndProc (HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
	// Check which message was passed in
    switch (iMsg)
    {
		case WM_COMMAND:							// Check if we have a command from the user
			HandleMenu(LOWORD(wParam));				// Pass in the command ID to our menu function
			break;

		case WM_MOUSEMOVE:							// If the mouse moves
			g_cursorPos.x = LOWORD(lParam);			// Store the current cursor position
			g_cursorPos.y = HIWORD(lParam);
			break;

		// This gets rid of unnecessary erasing of the window (eliminates flickering)
		case WM_ERASEBKGND:
			return 1;

		// This message is sent when the window is destroyed
		case WM_DESTROY:

			// Tell the window we need to close
			PostQuitMessage(0);
			break;

		// Process default messages
		default:
			return DefWindowProc (hWnd, iMsg, wParam, lParam);
	}

	// Return zero if we handle message
	return 0;
}

////////////////////////////////////////////////////////////////////
//
// *Quick Notes*
//
// In this file we added some small things for doing music and sound,
// as well as making sure we check if we run into Npcs so that we can
// display dialog.
//
// You can jump to Map.cpp for more of the beef of this tutorial, then
// skip over to Menu.cpp.  In the next tutorial we will handle the
// inventory system.  This means, picking up items, dropping them,
// adding equipment to the player, using items, etc...
//
// The music in this tutorial was created by Bjorn Lynne (http://www.lynnemusic.com/).
//
//
// Ben Humphrey (DigiBen)
// Game Programmer
// DigiBen@GameTutorials.com
// Co-Web Host of www.GameTutorials.com
//
// © 2000-2005 GameTutorials


text:
"""Code for running the certification problem."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np
import tensorflow as tf

from cleverhans.experimental.certification import dual_formulation
from cleverhans.experimental.certification import neural_net_params
from cleverhans.experimental.certification import optimization
from cleverhans.experimental.certification import read_weights
from cleverhans.experimental.certification import utils

flags = tf.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_string('checkpoint', None,
                    'Path of checkpoint with trained model to verify')
flags.DEFINE_string('model_json', None,
                    'Path of json file with model description')
flags.DEFINE_string('init_dual_file', None,
                    'Path of numpy file with dual variables to initialize')
flags.DEFINE_string('test_input', None,
                    'Path of numpy file with test input to certify')
flags.DEFINE_integer('true_class', 0,
                     'True class of the test input')
flags.DEFINE_integer('adv_class', -1,
                     'target class of adversarial example; all classes if -1')
flags.DEFINE_float('input_minval', -1,
                   'Minimum value of valid input')
flags.DEFINE_float('input_maxval', 1,
                   'Maximum value of valid input')
flags.DEFINE_float('epsilon', 0.2,
                   'Size of perturbation')
# Nu might need tuning based on the network
flags.DEFINE_float('init_nu', 300.0,
                   'Initialization of nu variable.')
flags.DEFINE_float('init_penalty', 100.0,
                   'Initial penalty')
flags.DEFINE_integer('small_eig_num_steps', 500,
                     'Number of eigen value steps in intermediate iterations')
flags.DEFINE_integer('large_eig_num_steps', 5000,
                     'Number of eigen value steps in each outer iteration')
flags.DEFINE_integer('inner_num_steps', 600,
                     'Number of steps to run in inner loop')
flags.DEFINE_float('outer_num_steps', 10,
                   'Number of steps to run in outer loop')
flags.DEFINE_float('beta', 2,
                   'Multiplicative factor to increase penalty by')
flags.DEFINE_float('smoothness_parameter', 0.001,
                   'Smoothness parameter if using eigen decomposition')
flags.DEFINE_float('eig_learning_rate', 0.001,
                   'Learning rate for computing min eigen value')
flags.DEFINE_string('optimizer', 'adam',
                    'Optimizer to use for entire optimization')
flags.DEFINE_float('init_learning_rate', 0.1,
                   'Initial learning rate')
flags.DEFINE_float('learning_rate_decay', 0.1,
                   'Decay of learning rate')
flags.DEFINE_float('momentum_parameter', 0.9,
                   'Momentum parameter if using momentum optimizer')
flags.DEFINE_integer('print_stats_steps', 50,
                     'Number of steps to print stats after')
flags.DEFINE_string('stats_folder', None,
                    'Folder to save stats of the iterations')
flags.DEFINE_integer('projection_steps', 200,
                     'Number of steps to compute projection after')
flags.DEFINE_integer('num_classes', 10,
                     'Total number of classes')

def main(_):
  net_weights, net_biases, net_layer_types = read_weights.read_weights(
      FLAGS.checkpoint, FLAGS.model_json)
  nn_params = neural_net_params.NeuralNetParams(
      net_weights, net_biases, net_layer_types)
  print(nn_params.sizes)
  dual_var = utils.initialize_dual(nn_params, FLAGS.init_dual_file,
                                   init_nu=FLAGS.init_nu)
  # Reading test input and reshaping
  with tf.gfile.Open(FLAGS.test_input) as f:
    test_input = np.load(f)
  test_input = np.reshape(test_input, [np.size(test_input), 1])

  if FLAGS.adv_class == -1:
    start_class = 0
    end_class = FLAGS.num_classes
  else:
    start_class = FLAGS.adv_class
    end_class = FLAGS.adv_class + 1
  for adv_class in range(start_class, end_class):
    print('Adv class', adv_class)
    if adv_class == FLAGS.true_class:
      continue
    dual = dual_formulation.DualFormulation(dual_var,
                                            nn_params,
                                            test_input,
                                            FLAGS.true_class,
                                            adv_class,
                                            FLAGS.input_minval,
                                            FLAGS.input_maxval,
                                            FLAGS.epsilon)
    dual.set_differentiable_objective()
    dual.get_full_psd_matrix()
    optimization_params = {
        'init_penalty': FLAGS.init_penalty,
        'large_eig_num_steps': FLAGS.large_eig_num_steps,
        'small_eig_num_steps': FLAGS.small_eig_num_steps,
        'inner_num_steps': FLAGS.inner_num_steps,
        'outer_num_steps': FLAGS.outer_num_steps,
        'beta': FLAGS.beta,
        'smoothness_parameter': FLAGS.smoothness_parameter,
        'eig_learning_rate': FLAGS.eig_learning_rate,
        'optimizer': FLAGS.optimizer,
        'init_learning_rate': FLAGS.init_learning_rate,
        'learning_rate_decay': FLAGS.learning_rate_decay,
        'momentum_parameter': FLAGS.momentum_parameter,
        'print_stats_steps': FLAGS.print_stats_steps,
        'stats_folder': FLAGS.stats_folder,
        'projection_steps': FLAGS.projection_steps}
    with tf.Session() as sess:
      sess.run(tf.global_variables_initializer())
      optimization_object = optimization.Optimization(dual,
                                                      sess,
                                                      optimization_params)
      optimization_object.prepare_one_step()
      is_cert_found = optimization_object.run_optimization()
      if not is_cert_found:
        print('Current example could not be verified')
        exit()
  print('Example successfully verified')

if __name__ == '__main__':
  tf.app.run(main)


text:
<!DOCTYPE html>
<script src="../resources/js-test.js"></script>
<script src="../fast/dom/shadow/resources/shadow-dom.js"></script>
<body></body>
<script>
description("Tests for getDestinationInsertionPoints() which involves re-distribution.");

document.body.appendChild(
    createDOM('div', {},
              createDOM('div', {'id': 'host-1'},
                        createShadowRoot(
                            createDOM('div', {'id': 'host-2'},
                                      createShadowRoot(
                                          createDOM('content', {'id': 'content-2'})),
                                      createDOM('content', {'id': 'content-1'}))),
                        createDOM('div', {'id': 'child-1'}))));

shouldBeEqualAsArray(document.getElementById('child-1').getDestinationInsertionPoints(),
                     [getNodeInComposedTree('host-1/content-1'), getNodeInComposedTree('host-1/host-2/content-2')]);

document.body.appendChild(
    createDOM('div', {},
              createDOM('div', {'id': 'host-10'},
                        createShadowRoot(
                            createDOM('div', {'id': 'host-20'},
                                      attachShadow(
                                          {'mode': 'open'},
                                          createDOM('content', {'id': 'content-20'})),
                                      createDOM('content', {'id': 'content-10'}))),
                        createDOM('div', {'id': 'child-10'}))));

shouldBeEqualAsArray(document.getElementById('child-10').getDestinationInsertionPoints(),
                     [getNodeInComposedTree('host-10/content-10')]);

document.body.appendChild(
    createDOM('div', {},
              createDOM('div', {'id': 'host-11'},
                        createShadowRoot(
                            createDOM('div', {'id': 'host-21'},
                                      attachShadow(
                                          {'mode': 'closed'},
                                          createDOM('content', {'id': 'content-21'})),
                                      createDOM('content', {'id': 'content-11'}))),
                        createDOM('div', {'id': 'child-11'}))));

shouldBeEqualAsArray(document.getElementById('child-11').getDestinationInsertionPoints(),
                     [getNodeInComposedTree('host-11/content-11')]);

document.body.appendChild(
    createDOM('div', {},
              createDOM('div', {'id': 'host-12'},
                        attachShadow(
                            {'mode': 'closed'},
                            createDOM('div', {'id': 'host-22'},
                                      createShadowRoot(
                                          createDOM('content', {'id': 'content-22'})),
                                      createDOM('content', {'id': 'content-12'}))),
                        createDOM('div', {'id': 'child-12'}))));

shouldBe('document.getElementById("child-12").getDestinationInsertionPoints().length', '0');
</script>


text:
define([
	'./List',
	'./_StoreMixin',
	'dojo/_base/declare',
	'dojo/_base/lang',
	'dojo/dom-construct',
	'dojo/on',
	'dojo/when',
	'./util/misc'
], function (List, _StoreMixin, declare, lang, domConstruct, on, when, miscUtil) {

	return declare([ List, _StoreMixin ], {
		// summary:
		//		Extends List to include virtual scrolling functionality, querying a
		//		dojo/store instance for the appropriate range when the user scrolls.

		// minRowsPerPage: Integer
		//		The minimum number of rows to request at one time.
		minRowsPerPage: 25,

		// maxRowsPerPage: Integer
		//		The maximum number of rows to request at one time.
		maxRowsPerPage: 250,

		// maxEmptySpace: Integer
		//		Defines the maximum size (in pixels) of unrendered space below the
		//		currently-rendered rows. Setting this to less than Infinity can be useful if you
		//		wish to limit the initial vertical scrolling of the grid so that the scrolling is
		// 		not excessively sensitive. With very large grids of data this may make scrolling
		//		easier to use, albiet it can limit the ability to instantly scroll to the end.
		maxEmptySpace: Infinity,

		// bufferRows: Integer
		//	  The number of rows to keep ready on each side of the viewport area so that the user can
		//	  perform local scrolling without seeing the grid being built. Increasing this number can
		//	  improve perceived performance when the data is being retrieved over a slow network.
		bufferRows: 10,

		// farOffRemoval: Integer
		//		Defines the minimum distance (in pixels) from the visible viewport area
		//		rows must be in order to be removed.  Setting to Infinity causes rows
		//		to never be removed.
		farOffRemoval: 2000,

		// queryRowsOverlap: Integer
		//		Indicates the number of rows to overlap queries. This helps keep
		//		continuous data when underlying data changes (and thus pages don't
		//		exactly align)
		queryRowsOverlap: 0,

		// pagingMethod: String
		//		Method (from dgrid/util/misc) to use to either throttle or debounce
		//		requests.  Default is "debounce" which will cause the grid to wait until
		//		the user pauses scrolling before firing any requests; can be set to
		//		"throttleDelayed" instead to progressively request as the user scrolls,
		//		which generally incurs more overhead but might appear more responsive.
		pagingMethod: 'debounce',

		// pagingDelay: Integer
		//		Indicates the delay (in milliseconds) imposed upon pagingMethod, to wait
		//		before paging in more data on scroll events. This can be increased to
		//		reduce client-side overhead or the number of requests sent to a server.
		pagingDelay: miscUtil.defaultDelay,

		// keepScrollPosition: Boolean
		//		When refreshing the list, controls whether the scroll position is
		//		preserved, or reset to the top.  This can also be overridden for
		//		specific calls to refresh.
		keepScrollPosition: false,

		// rowHeight: Number
		//		Average row height, computed in renderQuery during the rendering of
		//		the first range of data.
		rowHeight: 0,

		postCreate: function () {
			this.inherited(arguments);
			var self = this;
			// check visibility on scroll events
			on(this.bodyNode, 'scroll',
				miscUtil[this.pagingMethod](function (event) {
					self._processScroll(event);
				}, null, this.pagingDelay)
			);
		},

		destroy: function () {
			this.inherited(arguments);
			if (this._refreshTimeout) {
				clearTimeout(this._refreshTimeout);
			}
		},

		renderQuery: function (query, options) {
			// summary:
			//		Creates a preload node for rendering a query into, and executes the query
			//		for the first page of data. Subsequent data will be downloaded as it comes
			//		into view.
			// query: Function
			//		Function to be called when requesting new data.
			// options: Object?
			//		Optional object containing the following:
			//		* container: Container to build preload nodes within; defaults to this.contentNode

			var self = this,
				container = (options && options.container) || this.contentNode,
				preload = {
					query: query,
					count: 0
				},
				preloadNode,
				priorPreload = this.preload;

			// Initial query; set up top and bottom preload nodes
			var topPreload = {
				node: domConstruct.create('div', {
					className: 'dgrid-preload',
					style: { height: '0' }
				}, container),
				count: 0,
				query: query,
				next: preload
			};
			topPreload.node.rowIndex = 0;
			preload.node = preloadNode = domConstruct.create('div', {
				className: 'dgrid-preload'
			}, container);
			preload.previous = topPreload;

			// this preload node is used to represent the area of the grid that hasn't been
			// downloaded yet
			preloadNode.rowIndex = this.minRowsPerPage;

			if (priorPreload) {
				// the preload nodes (if there are multiple) are represented as a linked list, need to insert it
				if ((preload.next = priorPreload.next) &&
						// is this preload node below the prior preload node?
						preloadNode.offsetTop >= priorPreload.node.offsetTop) {
					// the prior preload is above/before in the linked list
					preload.previous = priorPreload;
				}
				else {
					// the prior preload is below/after in the linked list
					preload.next = priorPreload;
					preload.previous = priorPreload.previous;
				}
				// adjust the previous and next links so the linked list is proper
				preload.previous.next = preload;
				preload.next.previous = preload;
			}
			else {
				this.preload = preload;
			}

			var loadingNode = domConstruct.create('div', {
					className: 'dgrid-loading'
				}, preloadNode, 'before'),
				innerNode = domConstruct.create('div', {
					className: 'dgrid-below'
				}, loadingNode);
			innerNode.innerHTML = this.loadingMessage;

			// Establish query options, mixing in our own.
			options = lang.mixin({ start: 0, count: this.minRowsPerPage },
				'level' in query ? { queryLevel: query.level } : null);

			// Protect the query within a _trackError call, but return the resulting collection
			return this._trackError(function () {
				var results = query(options);

				// Render the result set
				return self.renderQueryResults(results, preloadNode, options).then(function (trs) {
					return results.totalLength.then(function (total) {
						var trCount = trs.length,
							parentNode = preloadNode.parentNode,
							noDataNode = self.noDataNode;

						if (self._rows) {
							self._rows.min = 0;
							self._rows.max = trCount === total ? Infinity : trCount - 1;
						}

						domConstruct.destroy(loadingNode);
						if (!('queryLevel' in options)) {
							self._total = total;
						}
						// now we need to adjust the height and total count based on the first result set
						if (total === 0 && parentNode) {
							if (noDataNode) {
								domConstruct.destroy(noDataNode);
								delete self.noDataNode;
							}
							self.noDataNode = noDataNode = domConstruct.create('div', {
								className: 'dgrid-no-data',
								innerHTML: self.noDataMessage
							});
							parentNode.insertBefore(noDataNode, self._getFirstRowSibling(parentNode));
						}
						var height = 0;
						for (var i = 0; i < trCount; i++) {
							height += self._calcRowHeight(trs[i]);
						}
						// only update rowHeight if we actually got results and are visible
						if (trCount && height) {
							self.rowHeight = height / trCount;
						}

						total -= trCount;
						preload.count = total;
						preloadNode.rowIndex = trCount;
						if (total) {
							preloadNode.style.height = Math.min(total * self.rowHeight, self.maxEmptySpace) + 'px';
						}
						else {
							preloadNode.style.display = 'none';
						}

						if (self._previousScrollPosition) {
							// Restore position after a refresh operation w/ keepScrollPosition
							self.scrollTo(self._previousScrollPosition);
							delete self._previousScrollPosition;
						}

						// Redo scroll processing in case the query didn't fill the screen,
						// or in case scroll position was restored
						return when(self._processScroll()).then(function () {
							return trs;
						});
					});
				}).otherwise(function (err) {
					// remove the loadingNode and re-throw
					domConstruct.destroy(loadingNode);
					throw err;
				});
			});
		},

		refresh: function (options) {
			// summary:
			//		Refreshes the contents of the grid.
			// options: Object?
			//		Optional object, supporting the following parameters:
			//		* keepScrollPosition: like the keepScrollPosition instance property;
			//			specifying it in the options here will override the instance
			//			property's value for this specific refresh call only.

			var self = this,
				keep = (options && options.keepScrollPosition);

			// Fall back to instance property if option is not defined
			if (typeof keep === 'undefined') {
				keep = this.keepScrollPosition;
			}

			// Store scroll position to be restored after new total is received
			if (keep) {
				this._previousScrollPosition = this.getScrollPosition();
			}

			this.inherited(arguments);
			if (this._renderedCollection) {
				// render the query

				// renderQuery calls _trackError internally
				return this.renderQuery(function (queryOptions) {
					return self._renderedCollection.fetchRange({
						start: queryOptions.start,
						end: queryOptions.start + queryOptions.count
					});
				}).then(function () {
					// Emit on a separate turn to enable event to be used consistently for
					// initial render, regardless of whether the backing store is async
					self._refreshTimeout = setTimeout(function () {
						on.emit(self.domNode, 'dgrid-refresh-complete', {
							bubbles: true,
							cancelable: false,
							grid: self
						});
						self._refreshTimeout = null;
					}, 0);
				});
			}
		},

		resize: function () {
			this.inherited(arguments);
			this._processScroll();
		},

		cleanup: function () {
			this.inherited(arguments);
			this.preload = null;
		},

		renderQueryResults: function (results) {
			var rows = this.inherited(arguments);
			var collection = this._renderedCollection;

			if (collection && collection.releaseRange) {
				rows.then(function (resolvedRows) {
					if (resolvedRows[0] && !resolvedRows[0].parentNode.tagName) {
						// Release this range, since it was never actually rendered;
						// need to wait until totalLength promise resolves, since
						// Trackable only adds the range then to begin with
						results.totalLength.then(function () {
							collection.releaseRange(resolvedRows[0].rowIndex,
								resolvedRows[resolvedRows.length - 1].rowIndex + 1);
						});
					}
				});
			}

			return rows;
		},

		_getFirstRowSibling: function (container) {
			// summary:
			//		Returns the DOM node that a new row should be inserted before
			//		when there are no other rows in the current result set.
			//		In the case of OnDemandList, this will always be the last child
			//		of the container (which will be a trailing preload node).
			return container.lastChild;
		},

		_calcRowHeight: function (rowElement) {
			// summary:
			//		Calculate the height of a row. This is a method so it can be overriden for
			//		plugins that add connected elements to a row, like the tree

			var sibling = rowElement.nextSibling;

			// If a next row exists, compare the top of this row with the
			// next one (in case "rows" are actually rendering side-by-side).
			// If no next row exists, this is either the last or only row,
			// in which case we count its own height.
			if (sibling && !/\bdgrid-preload\b/.test(sibling.className)) {
				return sibling.offsetTop - rowElement.offsetTop;
			}

			return rowElement.offsetHeight;
		},

		lastScrollTop: 0,
		_processScroll: function (evt) {
			// summary:
			//		Checks to make sure that everything in the viewable area has been
			//		downloaded, and triggering a request for the necessary data when needed.

			if (!this.rowHeight) {
				return;
			}

			var grid = this,
				scrollNode = grid.bodyNode,
				// grab current visible top from event if provided, otherwise from node
				visibleTop = (evt && evt.scrollTop) || this.getScrollPosition().y,
				visibleBottom = scrollNode.offsetHeight + visibleTop,
				priorPreload, preloadNode, preload = grid.preload,
				lastScrollTop = grid.lastScrollTop,
				requestBuffer = grid.bufferRows * grid.rowHeight,
				searchBuffer = requestBuffer - grid.rowHeight, // Avoid rounding causing multiple queries
				// References related to emitting dgrid-refresh-complete if applicable
				lastRows,
				preloadSearchNext = true;

			// XXX: I do not know why this happens.
			// munging the actual location of the viewport relative to the preload node by a few pixels in either
			// direction is necessary because at least WebKit on Windows seems to have an error that causes it to
			// not quite get the entire element being focused in the viewport during keyboard navigation,
			// which means it becomes impossible to load more data using keyboard navigation because there is
			// no more data to scroll to to trigger the fetch.
			// 1 is arbitrary and just gets it to work correctly with our current test cases; don't wanna go
			// crazy and set it to a big number without understanding more about what is going on.
			// wondering if it has to do with border-box or something, but changing the border widths does not
			// seem to make it break more or less, so I do not know…
			var mungeAmount = 1;

			grid.lastScrollTop = visibleTop;

			function removeDistantNodes(preload, distanceOff, traversal, below) {
				// we check to see the the nodes are "far off"
				var farOffRemoval = grid.farOffRemoval,
					preloadNode = preload.node;
				// by checking to see if it is the farOffRemoval distance away
				if (distanceOff > 2 * farOffRemoval) {
					// there is a preloadNode that is far off;
					// remove rows until we get to in the current viewport
					var row;
					var nextRow = preloadNode[traversal];
					var reclaimedHeight = 0;
					var count = 0;
					var toDelete = [];
					var firstRowIndex = nextRow && nextRow.rowIndex;
					var lastRowIndex;

					while ((row = nextRow)) {
						var rowHeight = grid._calcRowHeight(row);
						if (reclaimedHeight + rowHeight + farOffRemoval > distanceOff ||
								(nextRow.className.indexOf('dgrid-row') < 0 &&
									nextRow.className.indexOf('dgrid-loading') < 0)) {
							// we have reclaimed enough rows or we have gone beyond grid rows
							break;
						}

						nextRow = row[traversal];
						reclaimedHeight += rowHeight;
						count += row.count || 1;
						// Just do cleanup here, as we will do a more efficient node destruction in a setTimeout below
						grid.removeRow(row, true);
						toDelete.push(row);

						if ('rowIndex' in row) {
							lastRowIndex = row.rowIndex;
						}
					}

					if (grid._renderedCollection.releaseRange &&
							typeof firstRowIndex === 'number' && typeof lastRowIndex === 'number') {
						// Note that currently child rows in Tree structures are never unrendered;
						// this logic will need to be revisited when that is addressed.

						// releaseRange is end-exclusive, and won't remove anything if start >= end.
						if (below) {
							grid._renderedCollection.releaseRange(lastRowIndex, firstRowIndex + 1);
						}
						else {
							grid._renderedCollection.releaseRange(firstRowIndex, lastRowIndex + 1);
						}

						grid._rows[below ? 'max' : 'min'] = lastRowIndex;
						if (grid._rows.max >= grid._total - 1) {
							grid._rows.max = Infinity;
						}
					}
					// now adjust the preloadNode based on the reclaimed space
					preload.count += count;
					if (below) {
						preloadNode.rowIndex -= count;
						adjustHeight(preload);
					}
					else {
						// if it is above, we can calculate the change in exact row changes,
						// which we must do to not mess with the scroll position
						preloadNode.style.height = (preloadNode.offsetHeight + reclaimedHeight) + 'px';
					}
					// we remove the elements after expanding the preload node so that
					// the contraction doesn't alter the scroll position
					var trashBin = document.createElement('div');
					for (var i = toDelete.length; i--;) {
						trashBin.appendChild(toDelete[i]);
					}
					setTimeout(function () {
						// we can defer the destruction until later
						domConstruct.destroy(trashBin);
					}, 1);
				}
			}

			function adjustHeight(preload, noMax) {
				preload.node.style.height = Math.min(preload.count * grid.rowHeight,
					noMax ? Infinity : grid.maxEmptySpace) + 'px';
			}
			function traversePreload(preload, moveNext) {
				// Skip past preloads that are not currently connected
				do {
					preload = moveNext ? preload.next : preload.previous;
				} while (preload && !preload.node.offsetWidth);
				return preload;
			}
			while (preload && !preload.node.offsetWidth) {
				// skip past preloads that are not currently connected
				preload = preload.previous;
			}
			// there can be multiple preloadNodes (if they split, or multiple queries are created),
			//	so we can traverse them until we find whatever is in the current viewport, making
			//	sure we don't backtrack
			while (preload && preload !== priorPreload) {
				priorPreload = grid.preload;
				grid.preload = preload;
				preloadNode = preload.node;
				var preloadTop = preloadNode.offsetTop;
				var preloadHeight;

				if (visibleBottom + mungeAmount + searchBuffer < preloadTop) {
					// the preload is below the line of sight
					preload = traversePreload(preload, (preloadSearchNext = false));
				}
				else if (visibleTop - mungeAmount - searchBuffer >
						(preloadTop + (preloadHeight = preloadNode.offsetHeight))) {
					// the preload is above the line of sight
					preload = traversePreload(preload, (preloadSearchNext = true));
				}
				else {
					// the preload node is visible, or close to visible, better show it
					var offset = ((preloadNode.rowIndex ? visibleTop - requestBuffer :
						visibleBottom) - preloadTop) / grid.rowHeight;
					var count = (visibleBottom - visibleTop + 2 * requestBuffer) / grid.rowHeight;
					// utilize momentum for predictions
					var momentum = Math.max(
						Math.min((visibleTop - lastScrollTop) * grid.rowHeight, grid.maxRowsPerPage / 2),
						grid.maxRowsPerPage / -2);
					count += Math.min(Math.abs(momentum), 10);
					if (preloadNode.rowIndex === 0) {
						// at the top, adjust from bottom to top
						offset -= count;
					}
					offset = Math.max(offset, 0);
					if (offset < 10 && offset > 0 && count + offset < grid.maxRowsPerPage) {
						// connect to the top of the preloadNode if possible to avoid excessive adjustments
						count += Math.max(0, offset);
						offset = 0;
					}
					count = Math.min(Math.max(count, grid.minRowsPerPage),
										grid.maxRowsPerPage, preload.count);

					if (count === 0) {
						preload = traversePreload(preload, preloadSearchNext);
						continue;
					}

					count = Math.ceil(count);
					offset = Math.min(Math.floor(offset), preload.count - count);

					var options = {};
					preload.count -= count;
					var beforeNode = preloadNode,
						keepScrollTo, queryRowsOverlap = grid.queryRowsOverlap,
						below = (preloadNode.rowIndex > 0 || preloadNode.offsetTop > visibleTop) && preload;
					if (below) {
						// add new rows below
						var previous = preload.previous;
						if (previous) {
							removeDistantNodes(previous,
								visibleTop - (previous.node.offsetTop + previous.node.offsetHeight),
								'nextSibling');
							if (offset > 0 && previous.node === preloadNode.previousSibling) {
								// all of the nodes above were removed
								offset = Math.min(preload.count, offset);
								preload.previous.count += offset;
								adjustHeight(preload.previous, true);
								preloadNode.rowIndex += offset;
								queryRowsOverlap = 0;
							}
							else {
								count += offset;
							}
							preload.count -= offset;
						}
						options.start = preloadNode.rowIndex - queryRowsOverlap;
						options.count = Math.min(count + queryRowsOverlap, grid.maxRowsPerPage);
						preloadNode.rowIndex = options.start + options.count;
					}
					else {
						// add new rows above
						if (preload.next) {
							// remove out of sight nodes first
							removeDistantNodes(preload.next, preload.next.node.offsetTop - visibleBottom,
								'previousSibling', true);
							beforeNode = preloadNode.nextSibling;
							if (beforeNode === preload.next.node) {
								// all of the nodes were removed, can position wherever we want
								preload.next.count += preload.count - offset;
								preload.next.node.rowIndex = offset + count;
								adjustHeight(preload.next);
								preload.count = offset;
								queryRowsOverlap = 0;
							}
							else {
								keepScrollTo = true;
							}

						}
						options.start = preload.count;
						options.count = Math.min(count + queryRowsOverlap, grid.maxRowsPerPage);
					}
					if (keepScrollTo && beforeNode && beforeNode.offsetWidth) {
						keepScrollTo = beforeNode.offsetTop;
					}

					adjustHeight(preload);

					// use the query associated with the preload node to get the next "page"
					if ('level' in preload.query) {
						options.queryLevel = preload.query.level;
					}

					// Avoid spurious queries (ideally this should be unnecessary...)
					if (!('queryLevel' in options) && (options.start > grid._total || options.count < 0)) {
						continue;
					}

					// create a loading node as a placeholder while the data is loaded
					var loadingNode = domConstruct.create('div', {
						className: 'dgrid-loading',
						style: { height: count * grid.rowHeight + 'px' }
					}, beforeNode, 'before');
					domConstruct.create('div', {
						className: 'dgrid-' + (below ? 'below' : 'above'),
						innerHTML: grid.loadingMessage
					}, loadingNode);
					loadingNode.count = count;

					// Query now to fill in these rows.
					grid._trackError(function () {
						// Use function to isolate the variables in case we make multiple requests
						// (which can happen if we need to render on both sides of an island of already-rendered rows)
						(function (loadingNode, below, keepScrollTo) {
							/* jshint maxlen: 122 */
							var rangeResults = preload.query(options);
							lastRows = grid.renderQueryResults(rangeResults, loadingNode, options).then(function (rows) {
								var gridRows = grid._rows;
								if (gridRows && !('queryLevel' in options) && rows.length) {
									// Update relevant observed range for top-level items
									if (below) {
										if (gridRows.max <= gridRows.min) {
											// All rows were removed; update start of rendered range as well
											gridRows.min = rows[0].rowIndex;
										}
										gridRows.max = rows[rows.length - 1].rowIndex;
									}
									else {
										if (gridRows.max <= gridRows.min) {
											// All rows were removed; update end of rendered range as well
											gridRows.max = rows[rows.length - 1].rowIndex;
										}
										gridRows.min = rows[0].rowIndex;
									}
								}

								// can remove the loading node now
								beforeNode = loadingNode.nextSibling;
								domConstruct.destroy(loadingNode);
								// beforeNode may have been removed if the query results loading node was removed
								// as a distant node before rendering
								if (keepScrollTo && beforeNode && beforeNode.offsetWidth) {
									// if the preload area above the nodes is approximated based on average
									// row height, we may need to adjust the scroll once they are filled in
									// so we don't "jump" in the scrolling position
									var pos = grid.getScrollPosition();
									grid.scrollTo({
										// Since we already had to query the scroll position,
										// include x to avoid TouchScroll querying it again on its end.
										x: pos.x,
										y: pos.y + beforeNode.offsetTop - keepScrollTo,
										// Don't kill momentum mid-scroll (for TouchScroll only).
										preserveMomentum: true
									});
								}

								rangeResults.totalLength.then(function (total) {
									if (!('queryLevel' in options)) {
										grid._total = total;
										if (grid._rows && grid._rows.max >= grid._total - 1) {
											grid._rows.max = Infinity;
										}
									}
									if (below) {
										// if it is below, we will use the total from the collection to update
										// the count of the last preload in case the total changes as
										// later pages are retrieved

										// recalculate the count
										below.count = total - below.node.rowIndex;
										// readjust the height
										adjustHeight(below);
									}
								});

								// make sure we have covered the visible area
								grid._processScroll();
								return rows;
							}, function (e) {
								domConstruct.destroy(loadingNode);
								throw e;
							});
						})(loadingNode, below, keepScrollTo);
					});

					preload = preload.previous;

				}
			}

			// return the promise from the last render
			return lastRows;
		}
	});

});


text:
<?php

namespace Emayk\Ics\Repo\Factory\Product;

use Emayk\Ics\Controllers\BaseController;

class Controller extends BaseController{
	protected $products;

	function __construct(iProduct $products)
	{
		$this->products = $products;
	}

	/**
	 * Display a listing of the resource.
	 *
	 * @return Response
	 */
	public function index()
	{
		return $this->products->all();
	}

	/**
	 * Show the form for creating a new resource.
	 *
	 * @return Response
	 */
	public function create()
	{
		return $this->products->create();
	}

	/**
	 * Store a newly created resource in storage.
	 *
	 * @return Response
	 */
	public function store()
	{
		return $this->products->store();
	}

	/**
	 * Display the specified resource.
	 *
	 * @param  int $id
	 *
	 * @return Response
	 */
	public function show($id)
	{
		return $this->products->show($id);
	}

	/**
	 * Show the form for editing the specified resource.
	 *
	 * @param  int $id
	 *
	 * @return Response
	 */
	public function edit($id)
	{
		return $this->products->edit($id);
	}

	/**
	 * Update the specified resource in storage.
	 *
	 * @param  int $id
	 *
	 * @return Response
	 */
	public function update($id)
	{
		return $this->products->update($id);
	}

	/**
	 * Remove the specified resource from storage.
	 *
	 * @param  int $id
	 *
	 * @return Response
	 */
	public function destroy($id)
	{
		return $this->products->destroy($id);
	}
}


text:
const queue = require('../../workers/queue');
const models = require("../../../models");
const i18n = require('../../utils/i18n');
const async = require('async');
const moment = require('moment');
const log = require('../../utils/logger');
const _ = require('lodash');
const docx = require('docx');
const fs = require('fs');

const { Document, Packer, Paragraph, Table, TableCell, UnderlineType, HeadingLevel, AlignmentType, Media, TableRow } = docx;

const getGroupPosts = require('./common_utils').getGroupPosts;
const getRatingHeaders = require('./common_utils').getRatingHeaders;
const getContactData = require('./common_utils').getContactData;
const getAttachmentData = require('./common_utils').getAttachmentData;
const getMediaTranscripts = require('./common_utils').getMediaTranscripts;
const getPostRatings = require('./common_utils').getPostRatings;
const getPostUrl =  require('./common_utils').getPostUrl;
const getLocation =  require('./common_utils').getLocation;
const getCategory =  require('./common_utils').getCategory;
const getUserEmail = require('./common_utils').getUserEmail;

const getMediaFormatUrl = require('./common_utils').getMediaFormatUrl;
const getMediaURLs = require('./common_utils').getMediaURLs;
const getPointsUpOrDown = require('./common_utils').getPointsUpOrDown;
const getPointsUp = require('./common_utils').getPointsUp;
const getPointsDown = require('./common_utils').getPointsDown;

const getTranslatedPoints = require('./common_utils').getTranslatedPoints;
const getTranslation = require('./common_utils').getTranslation;

const getOrderedPosts = require('./common_utils').getOrderedPosts;
const updateJobStatusIfNeeded = require('./common_utils').updateJobStatusIfNeeded;
const setJobError = require('./common_utils').setJobError;

const preparePosts = require('./common_utils').preparePosts;

const uploadToS3 =  require('./common_utils').uploadToS3;
const sanitizeFilename = require("sanitize-filename");
const getImageFromUrl =  require('./common_utils').getImageFromUrl;

const createDocWithStyles = (title) => {
  return new Document({
    creator: "Your Priorities Export",
    title: title,
    description: "Group export from Your Priorities",
    styles: {
      paragraphStyles: [
        {
          id: "Heading1",
          name: "Heading 1",
          basedOn: "Normal",
          next: "Normal",
          quickFormat: true,
          run: {
            size: 35,
            bold: true,
            italics: false,
            color: "black",
          },
          paragraph: {
            spacing: {
              after: 250,
              before: 100,
            },
          },
        },
        {
          id: "Heading2",
          name: "Heading 2",
          basedOn: "Normal",
          next: "Normal",
          quickFormat: true,
          run: {
            size: 26,
            bold: true,
            italics: false,
            color: "black",
          },
          paragraph: {
            spacing: {
              after: 140,
            },
          },
        },
        {
          id: "Heading3",
          name: "Heading 3",
          basedOn: "Normal",
          next: "Normal",
          quickFormat: true,
          run: {
            size: 65,
            bold: true
          },
          paragraph: {
            spacing: {
              before: 600,
              after: 120,
            },

          },
        },
        {
          id: "aside",
          name: "Aside",
          basedOn: "Normal",
          next: "Normal",
          run: {
            color: "999999",
            italics: true,
          },
          paragraph: {
            indent: {
              left: 720,
            },
            spacing: {
              line: 276,
            },
          },
        },
        {
          id: "wellSpaced",
          name: "Well Spaced",
          basedOn: "Normal",
          quickFormat: true,
          paragraph: {
            spacing: { line: 276, before: 20 * 72 * 0.1, after: 20 * 72 * 0.05 },
          },
        },
        {
          id: "ListParagraph",
          name: "List Paragraph",
          basedOn: "Normal",
          quickFormat: true,
        },
      ],
    }
  });
};

const setDescriptions = (group, post, builtPost, children) => {
  if (group && group.configuration && group.configuration.structuredQuestionsJson) {
    const questionsById = {};
    const questionComponents = group.configuration.structuredQuestionsJson;

    for (let i = 0; i < questionComponents.length; i++) {
      questionsById[questionComponents[i].uniqueId] = questionComponents[i];
    }

    const answers = post.public_data.structuredAnswersJson;

    if (answers) {
      for (let i = 0; i < answers.length; i += 1) {
        if (answers[i] && answers[i].uniqueId) {
          if (questionsById[answers[i].uniqueId]) {
            if (answers[i].value) {
              children.push(
                new Paragraph({
                  text: questionsById[answers[i].uniqueId].text,
                  heading: HeadingLevel.HEADING_2,
                }),
                new Paragraph(answers[i].value),
              )
            }
          } else {
            log.error("Can't find question for answer by id");
          }
        }
      }
    } else {
      log.error("No answers in post");
    }
  } else if (group && group.configuration && group.configuration.structuredQuestions && group.configuration.structuredQuestions!=="") {
    var structuredAnswers = [];

    var questionComponents = group.configuration.structuredQuestions.split(",");
    for (var i=0 ; i<questionComponents.length; i+=2) {
      var question = questionComponents[i];
      var maxLength = questionComponents[i+1];
      structuredAnswers.push({
        translatedQuestion: question.trim(),
        question: question,
        maxLength: maxLength, value: ""
      });
    }

    if (post.public_data && post.public_data.structuredAnswers && post.public_data.structuredAnswers!=="") {
      var answers = post.public_data.structuredAnswers.split("%!#x");
      for (i=0 ; i<answers.length; i+=1) {
        if (structuredAnswers[i])
          structuredAnswers[i].value = answers[i].trim();
      }
    } else {
      structuredAnswers[0].value = post.description;
    }

    structuredAnswers.forEach((questionAnswer) => {
      children.push(
        new Paragraph({
          text: questionAnswer.translatedQuestion,
          heading: HeadingLevel.HEADING_2,
        }),
        new Paragraph(questionAnswer.value),
      )
    });
  } else {
    children.push(
      new Paragraph(builtPost.translatedDescription ? builtPost.translatedDescription : post.description)
    );
  }
};

const addPointTranslationIfNeeded = (group, post, point, children) => {
  if (post.translatedPoints && post.translatedPoints[point.id]) {
    children.push(
      new Paragraph(post.translatedPoints[point.id])
    );
  } else {
    children.push(
      new Paragraph(point.content)
    );
  }

  if (point.public_data && point.public_data.admin_comment && point.public_data.admin_comment.text) {
    children.push(
      new Paragraph("")
    );

    children.push(
      new Paragraph(group.translatedCustomAdminCommentsTitle || group.configuration.customAdminCommentsTitle || "Admin comment")
    );

    let text = (post.translatedPoints && post.translatedPoints[point.id + "adminComments"]) || point.public_data.admin_comment.text || "";

    children.push(
      new Paragraph(text)
    );
  }

  children.push(
    new Paragraph("")
  );
};

const addPostToDoc = (doc, post, group) => {
  const children = [
    new Paragraph({
      text: post.translatedName ? post.translatedName : post.name,
      heading: HeadingLevel.HEADING_1,
    })
  ];

  setDescriptions(group, post.realPost, post, children);

  children.push(
    new Paragraph(""),
    new Paragraph("Original locale: "+post.realPost.language),
    new Paragraph("URL: "+ post.url),
    new Paragraph(""),
    new Paragraph("User email: "+ post.userEmail),
    new Paragraph("User name: "+ post.userName),
    new Paragraph(""),
    new Paragraph("Endorsements up: "+ post.endorsementsUp),
    new Paragraph("Endorsements down: "+ post.endorsementsDown),
    new Paragraph("Counter points: "+ post.counterPoints),
    new Paragraph("")
  );

  if (post.images && post.images.length>5) {
    children.push(
      new Paragraph("Image URLs: "+ post.images)
    );
    children.push(
      new Paragraph("")
    );
  }

  if (post.postRatings) {
    children.push(
      new Paragraph("Ratings: "+ post.postRatings)
    )
  }

  if (post.mediaURLs && post.mediaURLs.length>4) {
    children.push(
      new Paragraph("Media URLs: "+ post.mediaURLs)
    )
  }

  if (post.category) {
    children.push(
      new Paragraph("Category: "+ post.category)
    )
  }

  if (post.location && post.location.length>6) {
    children.push(
      new Paragraph("Location: "+ post.location)
    )
  }

  if (post.mediaTranscripts && post.mediaTranscripts.length>4) {
    children.push(
      new Paragraph("")
    );
    children.push(
      new Paragraph("Media transcripts: \n"+ post.mediaTranscripts)
    )
  }

  if (post.contactData && post.contactData.length>4) {
    children.push(
      new Paragraph("ContactData: "+ post.contactData)
    )
  }

  if (post.attachmentData && post.attachmentData.length>4) {
    children.push(
      new Paragraph("Attachment data: "+ post.attachmentData)
    )
  }

  const pointsUp = getPointsUp(post);

  let pointForText = group.translatedAlternativePointForHeader || group.configuration.alternativePointForHeader || 'Points for';
  let pointAgainstHeader =  group.translatedAlternativePointAgainstHeader || group.configuration.alternativePointAgainstHeader || 'Points against';

  children.push(
    new Paragraph({
      text: pointsUp.length>0 ? pointForText : "No points for",
      heading: HeadingLevel.HEADING_2,
    }));

  pointsUp.forEach((point) => {
    addPointTranslationIfNeeded(group, post, point, children);
  });

  const pointsDown = getPointsDown(post);
  children.push(
    new Paragraph({
      text: pointsDown.length>0 ? pointAgainstHeader : "No points against",
      heading: HeadingLevel.HEADING_2,
    }),
  );

  pointsDown.forEach((point) => {
    addPointTranslationIfNeeded(group, post, point, children);
  });

  doc.addSection({
    children: children
  });
};

const setupGroup = (doc, group, ratingsHeaders, title, done) => {
  let imageUrl, imageFilename;
  if (group.GroupLogoImages && group.GroupLogoImages.length>0) {
    const firstImageFormats =  JSON.parse(group.GroupLogoImages[0].formats);
    imageUrl = firstImageFormats[1];
  }

  async.series([
    (seriesCallback) => {
      if (imageUrl) {
        getImageFromUrl(imageUrl, (error, imageFile) => {
          if (error) {
            seriesCallback(error)
          } else {
            imageFilename = imageFile;
            seriesCallback();
          }
        })
      } else {
        seriesCallback();
      }
    },

    (seriesCallback) => {
      const children = [];

      if (imageFilename) {
        const image1 = Media.addImage(doc, fs.readFileSync(imageFilename), 432,243);
        children.push(new Paragraph(image1));
      }

      children.push(
        new Paragraph({
          text: title,
          heading: HeadingLevel.HEADING_1,
        }),

        new Paragraph({
          text: group.translatedName ? group.translatedName : group.name,
          heading: HeadingLevel.HEADING_1,
        }),

        new Paragraph(group.translatedObjectives ? group.translatedObjectives : group.objectives)
      );

      if (ratingsHeaders && ratingsHeaders.length>5) {
        children.push(
          new Paragraph({
            text: "Ratings options",
            heading: HeadingLevel.HEADING_1,
          }),

          new Paragraph(ratingsHeaders)
        );
      }

      if (group.targetTranslationLanguage) {
        children.push(
          new Paragraph(""),
          new Paragraph({
            text: "Automatically machine translated to locale: "+group.targetTranslationLanguage.toUpperCase(),
            heading: HeadingLevel.HEADING_2,
          }),
          new Paragraph("")
        )
      }

      doc.addSection({
        children: children
      });

      seriesCallback();
    }
  ],(error) => {
    done(error);
  })
};

const exportToDocx = (options, callback) => {
  const jobId = options.jobId;
  const groupId = options.groupId;
  const group = options.group;
  const posts = options.posts;
  let categories = options.categories;
  const customRatings = options.customRatings;

  const title = "Export for Group Id: "+group.id;

  const ratingsHeaders = getRatingHeaders(customRatings);

  const doc = createDocWithStyles(title);

  let processedCount = 0;
  let lastReportedCount = 0;
  const totalPostCount = posts.length;

  setupGroup(doc, group, ratingsHeaders, title, (error) => {
    if (error) {
      callback(error)
    } else {
      if (categories.length===0) {
        async.eachSeries(getOrderedPosts(posts), (post, eachCallback) =>{
          addPostToDoc(doc, post, group);
          processedCount += 1;
          updateJobStatusIfNeeded(jobId, totalPostCount, processedCount, lastReportedCount, (error, haveSent) => {
            if (haveSent)
              lastReportedCount = processedCount;
            eachCallback(error)
          })
        }, (error) => {
          if (error) {
            callback(error);
          } else {
            Packer.toBase64String(doc).then(b64string=>{
              callback(null, Buffer.from(b64string, 'base64'));
            });
          }
        });
      } else {
        async.series([
          (seriesCallback) => {
            categories = _.orderBy(categories, [category=>category]);
            async.eachSeries(categories, (category, categoryCallback) => {
              const children = [
                new Paragraph({
                  text: category,
                  heading: HeadingLevel.HEADING_3,
                  alignment: AlignmentType.CENTER
                })
              ];

              doc.addSection({
                children: children
              });

              async.eachSeries(getOrderedPosts(posts), (post, eachCallback) =>{
                if (post.category===category) {
                  addPostToDoc(doc, post, group);
                  processedCount += 1;
                  updateJobStatusIfNeeded(jobId, totalPostCount, processedCount, lastReportedCount, (error, haveSent) => {
                    if (haveSent) {
                      lastReportedCount = processedCount;
                    }
                    eachCallback(error)
                  })
                } else {
                  eachCallback();
                }
              }, (error) => {
                categoryCallback(error);
              });
            }, (error) => {
              seriesCallback(error);
            });
          },
          (seriesCallback) => {
            const postsWithoutCategories = [];
            posts.forEach((post) =>{
              if (!post.category) {
                postsWithoutCategories.push(post);
              }
            });

            if (postsWithoutCategories.length>0) {
              doc.addSection({
                children: [
                  new Paragraph({
                    text: "Posts without a category",
                    heading: HeadingLevel.HEADING_1,
                  })
                ]
              });

              async.eachSeries(getOrderedPosts(postsWithoutCategories), (post, eachCallback) =>{
                addPostToDoc(doc, post, group);
                processedCount += 1;
                updateJobStatusIfNeeded(jobId, totalPostCount, processedCount, lastReportedCount, (error, haveSent) => {
                  if (haveSent) {
                    lastReportedCount = processedCount;
                  }
                  eachCallback(error)
                })
              }, (error) => {
                seriesCallback(error);
              });
            } else {
              seriesCallback();
            }
          },
        ], (error) => {
          if (error) {
            callback(error);
          } else {
            Packer.toBase64String(doc).then(b64string=>{
              callback(null, Buffer.from(b64string, 'base64'));
            });
          }
        });
      }
    }

  });
};

const createDocxReport = (workPackage, callback) => {
  let exportOptions, exportedData, filename;

  async.series([
    (seriesCallback) => {
      models.Group.findOne({
        where: {
          id: workPackage.groupId
        },
        attributes: ['id','name','objectives','configuration','community_id'],
        include: [
          {
            model: models.Image,
            as: 'GroupLogoImages',
            attributes:  models.Image.defaultAttributesPublic,
            required: false
          }
        ],
        order: [
          [ { model: models.Image, as: 'GroupLogoImages' } , 'created_at', 'desc' ],
        ]
      }).then((group) => {
        workPackage.group = group;
        const dateString = moment(new Date()).format("DD_MM_YY_HH_mm");
        const groupName = sanitizeFilename(group.name).replace(/ /g,'');
        workPackage.filename = 'Ideas_and_Points_Group_Export_'+group.community_id+'_'+group.id+'_'+
          groupName+'_'+dateString+'.'+workPackage.exportType;
        seriesCallback();
      }).catch( error => {
        seriesCallback(error);
      })
    },
    (seriesCallback) => {
      preparePosts(workPackage, (error, options) => {
        exportOptions = options;
        seriesCallback(error);
      });
    },
    (seriesCallback) => {
      models.AcBackgroundJob.update(
        {
          progress: 5
        }, {
          where: { id: workPackage.jobId }
        }).then(()=>{
          seriesCallback();
        }).catch((error)=>{
         seriesCallback(error);
      });
    },
    (seriesCallback) => {
      exportToDocx(exportOptions, (error, data) => {
        exportedData = data;
        seriesCallback(error);
      });
    },
    (seriesCallback) => {
      uploadToS3(workPackage.jobId, workPackage.userId, workPackage.filename, workPackage.exportType, exportedData, (error, reportUrl) => {
        if (error) {
          seriesCallback(error);
        } else {
          models.AcBackgroundJob.update(
            {
              progress: 100,
              data: { reportUrl }
            }, {
              where: { id: workPackage.jobId }
            }).then(()=>{
            seriesCallback();
          }).catch((error)=>{
            seriesCallback(error);
          });
        }
      });
    }
  ], (error) => {
    if (error) {
      setJobError(workPackage.jobId, "errorDocxReportGeneration", error, dbError =>{
        callback(dbError || error);
      });
    } else {
      callback();
    }
  });
};

module.exports = {
  createDocxReport
};


text:
@class FeedItem;
@class FeedSource;
@class RSSParserService;

@protocol RSSParserServiceDelegate <NSObject>

- (void)handleParsedData:(NSArray <FeedItem *> *)feeds
           forFeedSource:(FeedSource *)feedSource
                  parser:(RSSParserService *)parserService;

@end

@interface RSSParserService : NSObject <NSXMLParserDelegate>

@property (nonatomic, strong) id<RSSParserServiceDelegate> delegate;

/// Parses RSS XML data for a given feed source.
- (void)parseData:(NSData *)data forFeedSource:(FeedSource *)feedSource;

@end


text:
exports.definition = {
	config: {
		columns: {
		    "title": "string",
		    "job_id": "string"
		},
		adapter: {
			type: "sql",
			collection_name: "job"
		}
	},
	extendModel: function(Model) {
		_.extend(Model.prototype, {
			// extended functions and properties go here
		});

		return Model;
	},
	extendCollection: function(Collection) {
		_.extend(Collection.prototype, {

			drop:function() {
				var db = Ti.Database.open("_alloy_");
				var result = db.execute("DELETE FROM job");
				db.close();
			}

		});

		return Collection;
	}
};