text:
'''
"compile" plugin for cocos command line tool
'''

__docformat__ = 'restructuredtext'

import cocos
import cocos_project
import subprocess
import os
import re
import sys
import shutil
import platform
import json
import build_web
if sys.platform == 'win32':
    import _winreg

class CCPluginCompile(cocos.CCPlugin):
    """
    compiles a project
    """

    BUILD_CONFIG_FILE = "build-cfg.json"
    CFG_KEY_WIN32_COPY_FILES = "copy_files"
    CFG_KEY_WIN32_MUST_COPY_FILES = "must_copy_files"

    CFG_KEY_COPY_RESOURCES = "copy_resources"
    CFG_KEY_MUST_COPY_RESOURCES = "must_copy_resources"

    OUTPUT_DIR_NATIVE = "bin"
    OUTPUT_DIR_SCRIPT_DEBUG = "runtime"
    OUTPUT_DIR_SCRIPT_RELEASE = "publish"

    PROJ_CFG_KEY_IOS_SIGN_ID = "ios_sign_id"
    PROJ_CFG_KEY_ENGINE_DIR = "engine_dir"

    BACKUP_SUFFIX = "-backup"
    ENGINE_JS_DIR = "frameworks/js-bindings/bindings/script"

    @staticmethod
    def plugin_name():
      return "compile"

    @staticmethod
    def brief_description():
        return "Compiles the current project to binary"

    def _add_custom_options(self, parser):
        from argparse import ArgumentParser
        parser.add_argument("-m", "--mode", dest="mode", default='debug',
                          help="Set the compile mode, should be debug|release, default is debug.")
        parser.add_argument("-j", "--jobs", dest="jobs", type=int,
                          help="Allow N jobs at once.")
        parser.add_argument("-o", "--output-dir", dest="output_dir", help="Specify the output directory.")

        group = parser.add_argument_group("Android Options")
        group.add_argument("--ap", dest="android_platform", help='Specify the android platform used for building android apk.')
        group.add_argument("--ndk-mode", dest="ndk_mode", help='Set the compile mode of ndk-build, should be debug|release|none, native code will not be compiled when the value is none. Default is same value with -m')
        group.add_argument("--app-abi", dest="app_abi", help='Set the APP_ABI of ndk-build. Can be multi value separated with ":".Sample : --app-aib armeabi:x86:mips. Default value is "armeabi".')
        group.add_argument("--ndk-toolchain", dest="toolchain", help='Specify the NDK_TOOLCHAIN of ndk-build.')
        group.add_argument("--ndk-cppflags", dest="cppflags", help='Specify the APP_CPPFLAGS of ndk-build.')

        group = parser.add_argument_group("Web Options")
        group.add_argument("--source-map", dest="source_map", action="store_true", help='Enable source-map')
        group.add_argument("--advanced", dest="advanced", action="store_true", help="Compile all source js files using Closure Compiler's advanced mode, bigger compression ratio bug more risk")

        group = parser.add_argument_group("iOS/Mac Options")
        group.add_argument("-t", "--target", dest="target_name", help="Specify the target name to compile.")

        group = parser.add_argument_group("iOS Options")
        group.add_argument("--sign-identity", dest="sign_id", help="The code sign identity for iOS.")

        group = parser.add_argument_group("lua/js project arguments")
        group.add_argument("--no-res", dest="no_res", action="store_true", help="Package without project resources.")
        group.add_argument("--compile-script", dest="compile_script", type=int, choices=[0, 1], help="Diable/Enable the compiling of lua/js script files.")

        group = parser.add_argument_group("lua project arguments")
        group.add_argument("--lua-encrypt", dest="lua_encrypt", action="store_true", help="Enable the encrypting of lua scripts.")
        group.add_argument("--lua-encrypt-key", dest="lua_encrypt_key", help="Specify the encrypt key for the encrypting of lua scripts.")
        group.add_argument("--lua-encrypt-sign", dest="lua_encrypt_sign", help="Specify the encrypt sign for the encrypting of lua scripts.")

        category = self.plugin_category()
        name = self.plugin_name()
        usage = "\n\t%%prog %s %s -p <platform> [-s src_dir][-m <debug|release>]" \
                "\nSample:" \
                "\n\t%%prog %s %s -p android" % (category, name, category, name)

    def _check_custom_options(self, args):

        if args.mode != 'release':
            args.mode = 'debug'

        self._mode = 'debug'
        if 'release' == args.mode:
            self._mode = args.mode

        # android arguments
        if args.ndk_mode is not None:
            self._ndk_mode = args.ndk_mode
        else:
            self._ndk_mode = self._mode

        self.app_abi = None
        if args.app_abi:
            self.app_abi = " ".join(args.app_abi.split(":"))

        self.cppflags = None
        if args.cppflags:
            self.cppflags = args.cppflags

        self.ndk_toolchain = None
        if args.toolchain:
            self.ndk_toolchain = args.toolchain

        # iOS/Mac arguments
        self.xcode_target_name = None
        if args.target_name is not None:
            self.xcode_target_name = args.target_name

        if args.compile_script is not None:
            self._compile_script = bool(args.compile_script)
        else:
            self._compile_script = (self._mode == "release")

        self._ap = args.android_platform

        if args.jobs is not None:
            self._jobs = args.jobs
        else:
            self._jobs = self.get_num_of_cpu()

        self._has_sourcemap = args.source_map
        self._web_advanced = args.advanced
        self._no_res = args.no_res

        if args.output_dir is None:
            self._output_dir = self._get_output_dir()
        else:
            if os.path.isabs(args.output_dir):
                self._output_dir = args.output_dir
            else:
                self._output_dir = os.path.abspath(args.output_dir)

        self._sign_id = args.sign_id

        if self._project._is_lua_project():
            self._lua_encrypt = args.lua_encrypt
            self._lua_encrypt_key = args.lua_encrypt_key
            self._lua_encrypt_sign = args.lua_encrypt_sign

        self._gen_custom_step_args()

    def get_num_of_cpu(self):
        try:
            platform = sys.platform
            if platform == 'win32':
                if 'NUMBER_OF_PROCESSORS' in os.environ:
                    return int(os.environ['NUMBER_OF_PROCESSORS'])
                else:
                    return 1
            else:
                from numpy.distutils import cpuinfo
                return cpuinfo.cpu._getNCPUs()
        except Exception:
            print "Can't know cpuinfo, use default 1 cpu"
            return 1

    def _get_output_dir(self):
        project_dir = self._project.get_project_dir()
        cur_platform = self._platforms.get_current_platform()
        if self._project._is_script_project():
            if self._mode == 'debug':
                output_dir = os.path.join(project_dir, CCPluginCompile.OUTPUT_DIR_SCRIPT_DEBUG, cur_platform)
            else:
                output_dir = os.path.join(project_dir, CCPluginCompile.OUTPUT_DIR_SCRIPT_RELEASE, cur_platform)
        else:
            output_dir = os.path.join(project_dir, CCPluginCompile.OUTPUT_DIR_NATIVE, self._mode, cur_platform)

        return output_dir

    def _gen_custom_step_args(self):
        self._custom_step_args = {
            "project-path": self._project.get_project_dir(),
            "platform-project-path": self._platforms.project_path(),
            "build-mode": self._mode,
            "output-dir": self._output_dir
        }

        if self._platforms.is_android_active():
            self._custom_step_args["ndk-build-mode"] = self._ndk_mode

    def _build_cfg_path(self):
        cur_cfg = self._platforms.get_current_config()
        if self._platforms.is_win32_active():
            if cur_cfg.build_cfg_path is not None:
                project_dir = self._project.get_project_dir()
                ret = os.path.join(project_dir, cur_cfg.build_cfg_path)
            else:
                ret = self._platforms.project_path()
        elif self._platforms.is_ios_active():
            ret = os.path.join(self._platforms.project_path(), "ios")
        elif self._platforms.is_mac_active():
            ret = os.path.join(self._platforms.project_path(), "mac")
        else:
            ret = self._platforms.project_path()

        return ret

    def _update_build_cfg(self):
        build_cfg_dir = self._build_cfg_path()
        cfg_file_path = os.path.join(build_cfg_dir, CCPluginCompile.BUILD_CONFIG_FILE)
        if not os.path.isfile(cfg_file_path):
            return

        key_of_copy = None
        key_of_must_copy = None
        if self._platforms.is_android_active():
            from build_android import AndroidBuilder
            key_of_copy = AndroidBuilder.CFG_KEY_COPY_TO_ASSETS
            key_of_must_copy = AndroidBuilder.CFG_KEY_MUST_COPY_TO_ASSERTS
        elif self._platforms.is_win32_active():
            key_of_copy = CCPluginCompile.CFG_KEY_WIN32_COPY_FILES
            key_of_must_copy = CCPluginCompile.CFG_KEY_WIN32_MUST_COPY_FILES

        if key_of_copy is None and key_of_must_copy is None:
            return

        try:
            outfile = None
            open_file = open(cfg_file_path)
            cfg_info = json.load(open_file)
            open_file.close()
            open_file = None
            changed = False
            if key_of_copy is not None:
                if cfg_info.has_key(key_of_copy):
                    src_list = cfg_info[key_of_copy]
                    ret_list = self._convert_cfg_list(src_list, build_cfg_dir)
                    cfg_info[CCPluginCompile.CFG_KEY_COPY_RESOURCES] = ret_list
                    del cfg_info[key_of_copy]
                    changed = True

            if key_of_must_copy is not None:
                if cfg_info.has_key(key_of_must_copy):
                    src_list = cfg_info[key_of_must_copy]
                    ret_list = self._convert_cfg_list(src_list, build_cfg_dir)
                    cfg_info[CCPluginCompile.CFG_KEY_MUST_COPY_RESOURCES] = ret_list
                    del cfg_info[key_of_must_copy]
                    changed = True

            if changed:
                # backup the old-cfg
                split_list = os.path.splitext(CCPluginCompile.BUILD_CONFIG_FILE)
                file_name = split_list[0]
                ext_name = split_list[1]
                bak_name = file_name + "-for-v0.1" + ext_name
                bak_file_path = os.path.join(build_cfg_dir, bak_name)
                if os.path.exists(bak_file_path):
                    os.remove(bak_file_path)
                os.rename(cfg_file_path, bak_file_path)

                # write the new data to file
                with open(cfg_file_path, 'w') as outfile:
                    json.dump(cfg_info, outfile, sort_keys = True, indent = 4)
                    outfile.close()
                    outfile = None
        finally:
            if open_file is not None:
                open_file.close()

            if outfile is not None:
                outfile.close()

    def _convert_cfg_list(self, src_list, build_cfg_dir):
        ret = []
        for element in src_list:
            ret_element = {}
            if str(element).endswith("/"):
                sub_str = element[0:len(element)-1]
                ret_element["from"] = sub_str
                ret_element["to"] = ""
            else:
                element_full_path = os.path.join(build_cfg_dir, element)
                if os.path.isfile(element_full_path):
                    to_dir = ""
                else:
                    to_dir = os.path.basename(element)
                ret_element["from"] = element
                ret_element["to"] = to_dir

            ret.append(ret_element)

        return ret

    def _is_debug_mode(self):
        return self._mode == 'debug'

    def _remove_file_with_ext(self, work_dir, ext):
        file_list = os.listdir(work_dir)
        for f in file_list:
            full_path = os.path.join(work_dir, f)
            if os.path.isdir(full_path):
                self._remove_file_with_ext(full_path, ext)
            elif os.path.isfile(full_path):
                name, cur_ext = os.path.splitext(f)
                if cur_ext == ext:
                    os.remove(full_path)

    def compile_scripts(self, src_dir, dst_dir):
        if not self._project._is_script_project():
            return

        if not self._compile_script:
            return

        cocos_cmd_path = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), "cocos")
        if self._project._is_lua_project():
            rm_ext = ".lua"
            compile_cmd = "\"%s\" luacompile -s \"%s\" -d \"%s\"" % (cocos_cmd_path, src_dir, dst_dir)
            if self._lua_encrypt:
                add_para = ""
                if self._lua_encrypt_key is not None:
                    add_para = "%s -k %s" % (add_para, self._lua_encrypt_key)

                if self._lua_encrypt_sign is not None:
                    add_para = "%s -b %s" % (add_para, self._lua_encrypt_sign)

                compile_cmd = "%s -e %s" % (compile_cmd, add_para)
        elif self._project._is_js_project():
            rm_ext = ".js"
            compile_cmd = "\"%s\" jscompile -s \"%s\" -d \"%s\"" % (cocos_cmd_path, src_dir, dst_dir)

        # run compile command
        self._run_cmd(compile_cmd)

        # remove the source scripts
        self._remove_file_with_ext(dst_dir, rm_ext)

    def build_android(self):
        if not self._platforms.is_android_active():
            return

        project_dir = self._project.get_project_dir()
        build_mode = self._mode
        output_dir = self._output_dir
        if self._project._is_script_project():
            if self._project._is_lua_project():
                cocos_root = os.path.join(project_dir, 'frameworks' ,'cocos2d-x')
            else:
                cocos_root = os.path.join(project_dir, 'frameworks' ,'%s-bindings' % self._project.get_language(), 'cocos2d-x')
        else:
            cocos_root = os.path.join(project_dir, 'cocos2d')

        # check environment variable
        ant_root = cocos.check_environment_variable('ANT_ROOT')
        sdk_root = cocos.check_environment_variable('ANDROID_SDK_ROOT')
        project_android_dir = self._platforms.project_path()

        from build_android import AndroidBuilder
        builder = AndroidBuilder(self._verbose, cocos_root, project_android_dir, self._no_res, self._project)

        args_ndk_copy = self._custom_step_args.copy()
        target_platform = self._platforms.get_current_platform()

        # update the project with the android platform
        builder.update_project(sdk_root, self._ap)

        if not self._project._is_script_project() or self._project._is_native_support():
            if self._ndk_mode != "none":
                # build native code
                cocos.Logging.info("building native")
                ndk_build_param = [
                    "-j%s" % self._jobs
                ]

                if self.app_abi:
                    abi_param = "APP_ABI=\"%s\"" % self.app_abi
                    ndk_build_param.append(abi_param)

                if self.ndk_toolchain:
                    toolchain_param = "NDK_TOOLCHAIN=%s" % self.ndk_toolchain
                    ndk_build_param.append(toolchain_param)

                self._project.invoke_custom_step_script(cocos_project.Project.CUSTOM_STEP_PRE_NDK_BUILD, target_platform, args_ndk_copy)

                modify_mk = False
                app_mk = os.path.join(project_android_dir, "jni/Application.mk")
                mk_content = None
                if self.cppflags and os.path.exists(app_mk):
                    # record the content of Application.mk
                    f = open(app_mk)
                    mk_content = f.read()
                    f.close()

                    # Add cpp flags
                    f = open(app_mk, "a")
                    f.write("\nAPP_CPPFLAGS += %s" % self.cppflags)
                    f.close()
                    modify_mk = True

                try:
                    builder.do_ndk_build(ndk_build_param, self._ndk_mode)
                except:
                    raise cocos.CCPluginError("Ndk build failed!")
                finally:
                    # roll-back the Application.mk
                    if modify_mk:
                        f = open(app_mk, "w")
                        f.write(mk_content)
                        f.close()

                self._project.invoke_custom_step_script(cocos_project.Project.CUSTOM_STEP_POST_NDK_BUILD, target_platform, args_ndk_copy)

        # build apk
        cocos.Logging.info("building apk")
        self.apk_path = builder.do_build_apk(sdk_root, ant_root, build_mode, output_dir, self._custom_step_args, self)

        cocos.Logging.info("build succeeded.")

    def check_ios_mac_build_depends(self):
        version = cocos.get_xcode_version()

        if version <= '5':
            message = "Update xcode please"
            raise cocos.CCPluginError(message)

        cfg_obj = self._platforms.get_current_config()
        if cfg_obj.proj_file is not None:
            xcodeproj_name = cfg_obj.proj_file
            name = os.path.basename(xcodeproj_name)
        else:
            name, xcodeproj_name = self.checkFileByExtention(".xcodeproj", self._platforms.project_path())
        if not xcodeproj_name:
            message = "Can't find the \".xcodeproj\" file"
            raise cocos.CCPluginError(message)

        self.project_name = name
        self.xcodeproj_name = xcodeproj_name

    def _remove_res(self, target_path):
        build_cfg_dir = self._build_cfg_path()
        cfg_file = os.path.join(build_cfg_dir, CCPluginCompile.BUILD_CONFIG_FILE)
        if os.path.exists(cfg_file) and os.path.isfile(cfg_file):
            # have config file
            open_file = open(cfg_file)
            cfg_info = json.load(open_file)
            open_file.close()
            if cfg_info.has_key("remove_res"):
                remove_list = cfg_info["remove_res"]
                for f in remove_list:
                    res = os.path.join(target_path, f)
                    if os.path.isdir(res):
                        # is a directory
                        if f.endswith('/'):
                            # remove files & dirs in it
                            for sub_file in os.listdir(res):
                                sub_file_fullpath = os.path.join(res, sub_file)
                                if os.path.isfile(sub_file_fullpath):
                                    os.remove(sub_file_fullpath)
                                elif os.path.isdir(sub_file_fullpath):
                                    shutil.rmtree(sub_file_fullpath)
                        else:
                            # remove the dir
                            shutil.rmtree(res)
                    elif os.path.isfile(res):
                        # is a file, remove it
                        os.remove(res)

    def get_engine_dir(self):
        engine_dir = self._project.get_proj_config(CCPluginCompile.PROJ_CFG_KEY_ENGINE_DIR)
        if engine_dir is None:
            engine_dir = self._project.get_project_dir()
        else:
            engine_dir = os.path.join(self._project.get_project_dir(), engine_dir)

        return engine_dir

    def backup_dir(self, dir_path):
        backup_dir = "%s%s" % (dir_path, CCPluginCompile.BACKUP_SUFFIX)
        if os.path.exists(backup_dir):
            shutil.rmtree(backup_dir)
        shutil.copytree(dir_path, backup_dir)

    def reset_backup_dir(self, dir_path):
        backup_dir = "%s%s" % (dir_path, CCPluginCompile.BACKUP_SUFFIX)
        if os.path.exists(dir_path):
            shutil.rmtree(dir_path)
        os.rename(backup_dir, dir_path)

    def build_ios(self):
        if not self._platforms.is_ios_active():
            return

        if not cocos.os_is_mac():
            raise cocos.CCPluginError("Please build on MacOSX")

        if self._sign_id is not None:
            cocos.Logging.info("Code Sign Identity: %s" % self._sign_id)
            self.use_sdk = 'iphoneos'
        else:
            self.use_sdk = 'iphonesimulator'

        self.check_ios_mac_build_depends()

        ios_project_dir = self._platforms.project_path()
        output_dir = self._output_dir

        projectPath = os.path.join(ios_project_dir, self.xcodeproj_name)
        pbxprojectPath = os.path.join(projectPath, "project.pbxproj")

        f = file(pbxprojectPath)
        contents = f.read()

        section = re.search(r"Begin PBXProject section.*End PBXProject section", contents, re.S)

        if section is None:
            message = "Can't find iOS target"
            raise cocos.CCPluginError(message)

        targets = re.search(r"targets = (.*);", section.group(), re.S)
        if targets is None:
            message = "Can't find iOS target"
            raise cocos.CCPluginError(message)

        targetName = None
        if self.xcode_target_name is not None:
            targetName = self.xcode_target_name
        else:
            cfg_obj = self._platforms.get_current_config()
            if cfg_obj.target_name is not None:
                targetName = cfg_obj.target_name
            else:
                names = re.split("\*", targets.group())
                for name in names:
                    if "iOS" in name:
                        targetName = str.strip(name)
                        break

        if targetName is None:
            message = "Can't find iOS target"
            raise cocos.CCPluginError(message)

        if os.path.isdir(output_dir):
            target_app_dir = os.path.join(output_dir, "%s.app" % targetName)
            if os.path.isdir(target_app_dir):
                shutil.rmtree(target_app_dir)

        # is script project & need compile scripts
        if self._project._is_script_project() and self._compile_script:
            # backup the source scripts
            script_src_dir = os.path.join(self._project.get_project_dir(), "src")
            self.backup_dir(script_src_dir)

            # compile the scripts
            self.compile_scripts(script_src_dir, script_src_dir)

            if self._project._is_js_project():
                # js project need compile the js files in engine
                engine_js_dir = os.path.join(self.get_engine_dir(), CCPluginCompile.ENGINE_JS_DIR)
                self.backup_dir(engine_js_dir)
                self.compile_scripts(engine_js_dir, engine_js_dir)

        try:
            cocos.Logging.info("building")

            command = ' '.join([
                "xcodebuild",
                "-project",
                "\"%s\"" % projectPath,
                "-configuration",
                "%s" % 'Debug' if self._mode == 'debug' else 'Release',
                "-target",
                "\"%s\"" % targetName,
                "%s" % "-arch i386" if self.use_sdk == 'iphonesimulator' else '',
                "-sdk",
                "%s" % self.use_sdk,
                "CONFIGURATION_BUILD_DIR=\"%s\"" % (output_dir),
                "%s" % "VALID_ARCHS=\"i386\"" if self.use_sdk == 'iphonesimulator' else ''
                ])

            if self._sign_id is not None:
                command = "%s CODE_SIGN_IDENTITY=\"%s\"" % (command, self._sign_id)

            self._run_cmd(command)

            filelist = os.listdir(output_dir)

            for filename in filelist:
                name, extention = os.path.splitext(filename)
                if extention == '.a':
                    filename = os.path.join(output_dir, filename)
                    os.remove(filename)

            self._iosapp_path = os.path.join(output_dir, "%s.app" % targetName)
            if self._no_res:
                self._remove_res(self._iosapp_path)

            if self._sign_id is not None:
                # generate the ipa
                app_path = os.path.join(output_dir, "%s.app" % targetName)
                ipa_path = os.path.join(output_dir, "%s.ipa" % targetName)
                ipa_cmd = "xcrun -sdk %s PackageApplication -v \"%s\" -o \"%s\"" % (self.use_sdk, app_path, ipa_path)
                self._run_cmd(ipa_cmd)

            cocos.Logging.info("build succeeded.")
        except:
            raise cocos.CCPluginError("Build failed: Take a look at the output above for details.")
        finally:
            # is script project & need compile scripts
            if self._project._is_script_project() and self._compile_script:
                script_src_dir = os.path.join(self._project.get_project_dir(), "src")
                self.reset_backup_dir(script_src_dir)

                if self._project._is_js_project():
                    engine_js_dir = os.path.join(self.get_engine_dir(), CCPluginCompile.ENGINE_JS_DIR)
                    self.reset_backup_dir(engine_js_dir)

    def build_mac(self):
        if not self._platforms.is_mac_active():
            return

        if not cocos.os_is_mac():
            raise cocos.CCPluginError("Please build on MacOSX")

        self.check_ios_mac_build_depends()

        mac_project_dir = self._platforms.project_path()
        output_dir = self._output_dir

        projectPath = os.path.join(mac_project_dir, self.xcodeproj_name)
        pbxprojectPath = os.path.join(projectPath, "project.pbxproj")

        f = file(pbxprojectPath)
        contents = f.read()

        section = re.search(
            r"Begin PBXProject section.*End PBXProject section",
            contents,
            re.S
        )

        if section is None:
            message = "Can't find Mac target"
            raise cocos.CCPluginError(message)

        targets = re.search(r"targets = (.*);", section.group(), re.S)
        if targets is None:
            message = "Can't find Mac target"
            raise cocos.CCPluginError(message)

        targetName = None
        if self.xcode_target_name is not None:
            targetName = self.xcode_target_name
        else:
            cfg_obj = self._platforms.get_current_config()
            if cfg_obj.target_name is not None:
                targetName = cfg_obj.target_name
            else:
                names = re.split("\*", targets.group())
                for name in names:
                    if "Mac" in name:
                        targetName = str.strip(name)

        if targetName is None:
            message = "Can't find Mac target"
            raise cocos.CCPluginError(message)

        if os.path.isdir(output_dir):
            target_app_dir = os.path.join(output_dir, "%s.app" % targetName)
            if os.path.isdir(target_app_dir):
                shutil.rmtree(target_app_dir)

        # is script project & need compile scripts
        if self._project._is_script_project() and self._compile_script:
            # backup the source scripts
            script_src_dir = os.path.join(self._project.get_project_dir(), "src")
            self.backup_dir(script_src_dir)

            # compile the scripts
            self.compile_scripts(script_src_dir, script_src_dir)

            if self._project._is_js_project():
                # js project need compile the js files in engine
                engine_js_dir = os.path.join(self.get_engine_dir(), CCPluginCompile.ENGINE_JS_DIR)
                self.backup_dir(engine_js_dir)
                self.compile_scripts(engine_js_dir, engine_js_dir)

        try:
            cocos.Logging.info("building")

            command = ' '.join([
                "xcodebuild",
                "-project",
                "\"%s\"" % projectPath,
                "-configuration",
                "%s" % 'Debug' if self._mode == 'debug' else 'Release',
                "-target",
                "\"%s\"" % targetName,
                "CONFIGURATION_BUILD_DIR=\"%s\"" % (output_dir)
                ])

            self._run_cmd(command)

            self.target_name = targetName
            filelist = os.listdir(output_dir)
            for filename in filelist:
                name, extention = os.path.splitext(filename)
                if extention == '.a':
                    filename = os.path.join(output_dir, filename)
                    os.remove(filename)

            self._macapp_path = os.path.join(output_dir, "%s.app" % targetName)
            if self._no_res:
                resource_path = os.path.join(self._macapp_path, "Contents", "Resources")
                self._remove_res(resource_path)

            cocos.Logging.info("build succeeded.")
        except:
            raise cocos.CCPluginError("Build failed: Take a look at the output above for details.")
        finally:
            # is script project & need compile scripts
            if self._project._is_script_project() and self._compile_script:
                script_src_dir = os.path.join(self._project.get_project_dir(), "src")
                self.reset_backup_dir(script_src_dir)

                if self._project._is_js_project():
                    engine_js_dir = os.path.join(self.get_engine_dir(), CCPluginCompile.ENGINE_JS_DIR)
                    self.reset_backup_dir(engine_js_dir)

    def _get_required_vs_version(self, proj_file):
        # get the VS version required by the project
        # file_obj = open(proj_file)
        # pattern = re.compile(r"^# Visual Studio.+(\d{4})")
        # num = None
        # for line in file_obj:
        #     match = pattern.match(line)
        #     if match is not None:
        #         num = match.group(1)
        #         break
        #
        # if num is not None:
        #     if num == "2012":
        #         ret = "11.0"
        #     elif num == "2013":
        #         ret = "12.0"
        #     else:
        #         ret = None
        # else:
        #     ret = None

        # Now VS2012 is the mini version required
        return "11.0"

    def _is_32bit_windows(self):
        arch = os.environ['PROCESSOR_ARCHITECTURE'].lower()
        archw = os.environ.has_key("PROCESSOR_ARCHITEW6432")
        return (arch == "x86" and not archw)

    def _get_vs_path(self, require_version):
        # find the VS in register, if system is 64bit, should find vs in both 32bit & 64bit register
        if self._is_32bit_windows():
            reg_flag_list = [ _winreg.KEY_WOW64_32KEY ]
        else:
            reg_flag_list = [ _winreg.KEY_WOW64_64KEY, _winreg.KEY_WOW64_32KEY ]

        needUpgrade = False
        vsPath = None

        try:
            for reg_flag in reg_flag_list:
                cocos.Logging.info("find vs in reg : %s" % ("32bit" if reg_flag == _winreg.KEY_WOW64_32KEY else "64bit"))
                vs = _winreg.OpenKey(
                    _winreg.HKEY_LOCAL_MACHINE,
                    r"SOFTWARE\Microsoft\VisualStudio",
                    0,
                    _winreg.KEY_READ | reg_flag
                )

                try:
                    i = 0
                    while True:
                        try:
                            # enum the keys in vs reg
                            try:
                                version = _winreg.EnumKey(vs, i)
                            except WindowsError:
                                break
                            find_ver = float(version)

                            # find the vs which version >= required version
                            if find_ver >= float(require_version):
                                key = _winreg.OpenKey(vs, r"SxS\VS7")
                                vsPath, type = _winreg.QueryValueEx(key, version)

                                if os.path.exists(vsPath):
                                    if float(version) > float(require_version):
                                        needUpgrade = True
                                    break
                                else:
                                    vsPath = None
                        except:
                            continue
                        finally:
                            i += 1
                except:
                    pass

                # if find one right vs, break
                if vsPath is not None:
                    break
        except WindowsError as e:
            message = "Visual Studio wasn't installed"
            print(e)
            raise cocos.CCPluginError(message)

        return (needUpgrade, vsPath)

    def build_win32(self):
        if not self._platforms.is_win32_active():
            return

        if not cocos.os_is_win32():
            raise cocos.CCPluginError("Please build on winodws")

        win32_projectdir = self._platforms.project_path()
        output_dir = self._output_dir

        cocos.Logging.info("building")

        # get the solution file & project name
        cfg_obj = self._platforms.get_current_config()
        if cfg_obj.sln_file is not None:
            sln_name = cfg_obj.sln_file
            if cfg_obj.project_name is None:
                raise cocos.CCPluginError("Must specified \"%s\" when \"%s\" is specified in file \"%s\"") % \
                      (cocos_project.Win32Config.KEY_PROJECT_NAME, cocos_project.Win32Config.KEY_SLN_FILE, cocos_project.Project.CONFIG)
            else:
                name = cfg_obj.project_name
        else:
            name, sln_name = self.checkFileByExtention(".sln", win32_projectdir)
            if not sln_name:
                message = "Can't find the \".sln\" file"
                raise cocos.CCPluginError(message)

        self.project_name = name
        projectPath = os.path.join(win32_projectdir, sln_name)

        # get the required VS version
        build_cfg_path = self._build_cfg_path()
        required_vs_version = self._get_required_vs_version(projectPath)
        if required_vs_version is None:
            raise cocos.CCPluginError("Can't parse the sln file to find required VS version")

        cocos.Logging.info("Required VS version : %s" % required_vs_version)

        # get the correct available VS path
        needUpgrade, vsPath = self._get_vs_path(required_vs_version)

        if vsPath is None:
            message = "Can't find correct Visual Studio's path in the regedit"
            raise cocos.CCPluginError(message)

        cocos.Logging.info("Find VS path : %s" % vsPath)

        commandPath = os.path.join(vsPath, "Common7", "IDE", "devenv")
        build_mode = 'Debug' if self._is_debug_mode() else 'Release'

        # upgrade projects
        if needUpgrade:
            commandUpgrade = ' '.join([
                "\"%s\"" % commandPath,
                "\"%s\"" % projectPath,
                "/Upgrade"
            ])
            self._run_cmd(commandUpgrade)

        # build the project
        commands = ' '.join([
            "\"%s\"" % commandPath,
            "\"%s\"" % projectPath,
            "/Build \"%s|Win32\"" % build_mode,
            "/Project \"%s\"" % self.project_name
        ])

        self._run_cmd(commands)

        cocos.Logging.info("build succeeded.")

        # copy files
        build_folder_name = "%s.win32" % build_mode
        build_folder_path = os.path.join(win32_projectdir, build_folder_name)
        if not os.path.isdir(build_folder_path):
            message = "Can not find the %s" % build_folder_path
            raise cocos.CCPluginError(message)

        # remove the files in output dir (keep the exe files)
        if os.path.exists(output_dir):
            output_files = os.listdir(output_dir)
            for element in output_files:
                ele_full_path = os.path.join(output_dir, element)
                if os.path.isfile(ele_full_path):
                    base_name, file_ext = os.path.splitext(element)
                    if not file_ext == ".exe":
                        os.remove(ele_full_path)
                elif os.path.isdir(ele_full_path):
                    shutil.rmtree(ele_full_path)

        # create output dir if it not existed
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        # copy dll & exe
        files = os.listdir(build_folder_path)
        for filename in files:
            name, ext = os.path.splitext(filename)
            proj_exe_name = "%s.exe" % self.project_name
            if ext == '.dll' or filename == proj_exe_name:
                file_path = os.path.join(build_folder_path, filename)
                cocos.Logging.info("Copying %s" % filename)
                shutil.copy(file_path, output_dir)

        # copy lua files & res
        build_cfg = os.path.join(build_cfg_path, CCPluginCompile.BUILD_CONFIG_FILE)
        if not os.path.exists(build_cfg):
            message = "%s not found" % build_cfg
            raise cocos.CCPluginError(message)
        f = open(build_cfg)
        data = json.load(f)

        if data.has_key(CCPluginCompile.CFG_KEY_MUST_COPY_RESOURCES):
            if self._no_res:
                fileList = data[CCPluginCompile.CFG_KEY_MUST_COPY_RESOURCES]
            else:
                fileList = data[CCPluginCompile.CFG_KEY_COPY_RESOURCES] + data[CCPluginCompile.CFG_KEY_MUST_COPY_RESOURCES]
        else:
            fileList = data[CCPluginCompile.CFG_KEY_COPY_RESOURCES]

        for cfg in fileList:
            cocos.copy_files_with_config(cfg, build_cfg_path, output_dir)

        # check the project config & compile the script files
        self.compile_scripts(output_dir, output_dir)

        self.run_root = output_dir

    def build_web(self):
        if not self._platforms.is_web_active():
            return

        project_dir = self._platforms.project_path()

        # store env for run
        cfg_obj = self._platforms.get_current_config()
        if cfg_obj.run_root_dir is not None:
            self.run_root = cfg_obj.run_root_dir
        else:
            self.run_root = project_dir

        if cfg_obj.sub_url is not None:
            self.sub_url = cfg_obj.sub_url
        else:
            self.sub_url = '/'

        output_dir = "publish"
        if self._is_debug_mode():
            output_dir = "runtime"
            if not self._web_advanced:
                return

        self.sub_url = '%s%s/html5/' % (self.sub_url, output_dir)

        f = open(os.path.join(project_dir, "project.json"))
        project_json = json.load(f)
        f.close()
        engine_dir = os.path.join(project_json["engineDir"])
        realEngineDir = os.path.normpath(os.path.join(project_dir, engine_dir))
        publish_dir = os.path.normpath(os.path.join(project_dir, output_dir, "html5"))

        # need to config in options of command
        buildOpt = {
                "outputFileName" : "game.min.js",
                "debug": "true" if self._is_debug_mode() else "false",
                "compilationLevel" : "advanced" if self._web_advanced else "simple",
                "sourceMapOpened" : True if self._has_sourcemap else False
                }

        if os.path.exists(publish_dir) == False:
            os.makedirs(publish_dir)

        # generate build.xml
        build_web.gen_buildxml(project_dir, project_json, publish_dir, buildOpt)

        outputJsPath = os.path.join(publish_dir, buildOpt["outputFileName"])
        if os.path.exists(outputJsPath) == True:
            os.remove(outputJsPath)

        # call closure compiler
        ant_root = cocos.check_environment_variable('ANT_ROOT')
        ant_path = os.path.join(ant_root, 'ant')
        self._run_cmd("%s -f %s" % (ant_path, os.path.join(publish_dir, 'build.xml')))

        # handle sourceMap
        sourceMapPath = os.path.join(publish_dir, "sourcemap")
        if os.path.exists(sourceMapPath):
            smFile = open(sourceMapPath)
            try:
                smContent = smFile.read()
            finally:
                smFile.close()

            dir_to_replace = project_dir
            if cocos.os_is_win32():
                dir_to_replace = project_dir.replace('\\', '\\\\')
            smContent = smContent.replace(dir_to_replace, os.path.relpath(project_dir, publish_dir))
            smContent = smContent.replace(realEngineDir, os.path.relpath(realEngineDir, publish_dir))
            smContent = smContent.replace('\\\\', '/')
            smContent = smContent.replace('\\', '/')
            smFile = open(sourceMapPath, "w")
            smFile.write(smContent)
            smFile.close()

        # handle project.json
        del project_json["engineDir"]
        del project_json["modules"]
        del project_json["jsList"]
        project_json_output_file = open(os.path.join(publish_dir, "project.json"), "w")
        project_json_output_file.write(json.dumps(project_json))
        project_json_output_file.close()

        # handle index.html
        indexHtmlFile = open(os.path.join(project_dir, "index.html"))
        try:
            indexContent = indexHtmlFile.read()
        finally:
            indexHtmlFile.close()
        reg1 = re.compile(r'<script\s+src\s*=\s*("|\')[^"\']*CCBoot\.js("|\')\s*><\/script>')
        indexContent = reg1.sub("", indexContent)
        mainJs = project_json.get("main") or "main.js"
        indexContent = indexContent.replace(mainJs, buildOpt["outputFileName"])
        indexHtmlOutputFile = open(os.path.join(publish_dir, "index.html"), "w")
        indexHtmlOutputFile.write(indexContent)
        indexHtmlOutputFile.close()

        # copy res dir
        dst_dir = os.path.join(publish_dir, 'res')
        src_dir = os.path.join(project_dir, 'res')
        if os.path.exists(dst_dir):
            shutil.rmtree(dst_dir)
        shutil.copytree(src_dir, dst_dir)

    def build_linux(self):
        if not self._platforms.is_linux_active():
            return

        #if not cocos.os_is_linux():
        #    raise cocos.CCPluginError("Please build on linux")

        project_dir = self._project.get_project_dir()
        cfg_obj = self._platforms.get_current_config()
        if cfg_obj.cmake_path is not None:
            cmakefile_dir = os.path.join(project_dir, cfg_obj.cmake_path)
        else:
            cmakefile_dir = project_dir
            if self._project._is_lua_project():
                cmakefile_dir = os.path.join(project_dir, 'frameworks')

        # get the project name
        if cfg_obj.project_name is not None:
            self.project_name = cfg_obj.project_name
        else:
            f = open(os.path.join(cmakefile_dir, 'CMakeLists.txt'), 'r')
            for line in f.readlines():
                if "set(APP_NAME " in line:
                    self.project_name = re.search('APP_NAME ([^\)]+)\)', line).group(1)
                    break

        if cfg_obj.build_dir is not None:
            build_dir = os.path.join(project_dir, cfg_obj.build_dir)
        else:
            build_dir = os.path.join(project_dir, 'linux-build')

        if not os.path.exists(build_dir):
            os.makedirs(build_dir)

        with cocos.pushd(build_dir):
            self._run_cmd('cmake %s' % os.path.relpath(cmakefile_dir, build_dir))

        with cocos.pushd(build_dir):
            self._run_cmd('make -j%s' % self._jobs)

        # move file
        output_dir = self._output_dir

        if os.path.exists(output_dir):
            shutil.rmtree(output_dir)
        os.makedirs(output_dir)

        if cfg_obj.build_result_dir is not None:
            result_dir = os.path.join(build_dir, 'bin', cfg_obj.build_result_dir)
        else:
            result_dir = os.path.join(build_dir, 'bin')
        cocos.copy_files_in_dir(result_dir, output_dir)

        self.run_root = output_dir

        if self._no_res:
            res_dir = os.path.join(output_dir, "Resources")
            self._remove_res(res_dir)

        if self._project._is_script_project() and self._compile_script:
            cocos.Logging.warning("Warning: Now script compiling is not supported for linux.")

        cocos.Logging.info('Build successed!')

    def checkFileByExtention(self, ext, path):
        filelist = os.listdir(path)
        for fullname in filelist:
            name, extention = os.path.splitext(fullname)
            if extention == ext:
                return name, fullname
        return (None, None)

    def run(self, argv, dependencies):
        self.parse_args(argv)
        cocos.Logging.info('Building mode: %s' % self._mode)
        self._update_build_cfg()

        target_platform = self._platforms.get_current_platform()
        args_build_copy = self._custom_step_args.copy()

        # invoke the custom step: pre-build
        self._project.invoke_custom_step_script(cocos_project.Project.CUSTOM_STEP_PRE_BUILD, target_platform, args_build_copy)

        self.build_android()
        self.build_ios()
        self.build_mac()
        self.build_win32()
        self.build_web()
        self.build_linux()

        # invoke the custom step: post-build
        self._project.invoke_custom_step_script(cocos_project.Project.CUSTOM_STEP_POST_BUILD, target_platform, args_build_copy)


text:
Use Cases » Raise money through a Seed Shares round
Raise money through a Seed Shares round
How to do it?
Step 1: Series A financing
Step 2: Series B financing
Step 3: Series C financing
Series A financing
Series B financing
Series C financing
Seed funding is the first official equity fundraising that a company uses to raise funds for further growth and expansion. The money raised during seed funding acts as a "seed" to grow that business into much larger enterprise. It helps the companies to finance their early goals and requirement that will take the company into new heights in the future. One of the most common types of investors in seed funding is "angel investors". An angel investor is a private investor who prefers to invest in a new startup in exchange for debt or ownership equity.
The Series A round begins when your business is generating enough consistent revenue (or is otherwise performing well in other areas) that you can justify pursuing larger sums from investors in order to grow your business further.
For example, perhaps you've launched a basic iteration of an app idea that's performed well during a test run in a relatively small market. You might then need additional funding to develop a stronger version of the app. To acquire it, you would thoroughly develop your strategy, presenting it to potential investors.
During the Series A round, investors who do choose to provide funding will usually invest between $2 million to $15 million, though these sums can vary depending on a range of factors.
The strategy you developed during the Series A round will ideally yield results when you use the funding you've secured to implement it. When this happens, you'll likely need more funding to ensure your business continues to grow at a consistent rate.
To return to the example above, after creating a stronger version of your app and growing your user base, you would probably need to fund marketing campaigns to help it reach even more users.
Once again, you would pursue this funding by presenting your strategy to investors and citing your current successes. During the Series B round, investors usually offer sums ranging between $7 million and $10 million.
By the time you reach the Series C round, your business will already be a proven success. You might now be ready to develop new products, acquire businesses offering products similar to yours, or continue expanding. Luckily, if you've reached this stage, convincing investors to provide funding will usually be easier.
Those who invest in your company during the Series C round plan to offer large sums with the expectation of a large payoff, knowing that investing in a successful company is much less risky than investing in an unproven idea. On average, a startup will raise $26 million during the Series C round.
It's common for startups to stop pursuing additional funding after Series C. That said, it's worth noting that some companies proceed to the Series E and Series F rounds if necessary.
Charlie Temple from Pave uses Zegal to record the binding terms in full that were discussed between parties during negotiation stage.
Issue New Shares
Ordinary Shares Investment Agreement
Ordinary Shares Investment Term Sheet
Share Subscription Letter

redpajama_set_name: RedPajamaCommonCrawl


text:
package libcore.net.spdy;

import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.util.List;
import libcore.io.Streams;
import libcore.util.Libcore;

import static java.nio.ByteOrder.BIG_ENDIAN;

/**
 * A logical bidirectional stream.
 */
public final class SpdyStream {

    /*
     * Internal state is guarded by this. No long-running or potentially
     * blocking operations are performed while the lock is held.
     */

    private static final int DATA_FRAME_HEADER_LENGTH = 8;

    public static final int RST_PROTOCOL_ERROR = 1;
    public static final int RST_INVALID_STREAM = 2;
    public static final int RST_REFUSED_STREAM = 3;
    public static final int RST_UNSUPPORTED_VERSION = 4;
    public static final int RST_CANCEL = 5;
    public static final int RST_INTERNAL_ERROR = 6;
    public static final int RST_FLOW_CONTROL_ERROR = 7;

    private final int id;
    private final SpdyConnection connection;

    /** Headers sent by the stream initiator. Immutable and non null. */
    private final List<String> requestHeaders;

    /** Headers sent in the stream reply. Null if reply is either not sent or not sent yet. */
    private List<String> responseHeaders;

    private final SpdyDataInputStream in = new SpdyDataInputStream();
    private final SpdyDataOutputStream out = new SpdyDataOutputStream();

    /**
     * The reason why this stream was abnormally closed. If there are multiple
     * reasons to abnormally close this stream (such as both peers closing it
     * near-simultaneously) then this is the first reason known to this peer.
     */
    private int rstStatusCode = -1;

    /**
     * True if either side has shut down the input stream. We will receive no
     * more bytes beyond those already in the buffer. Guarded by this.
     */
    private boolean inFinished;

    /**
     * True if either side has shut down the output stream. We will write no
     * more bytes to the output stream. Guarded by this.
     */
    private boolean outFinished;

    SpdyStream(int id, SpdyConnection connection, List<String> requestHeaders, int flags) {
        this.id = id;
        this.connection = connection;
        this.requestHeaders = requestHeaders;

        if (isLocallyInitiated()) {
            // I am the sender
            inFinished = (flags & SpdyConnection.FLAG_UNIDIRECTIONAL) != 0;
            outFinished = (flags & SpdyConnection.FLAG_FIN) != 0;
        } else {
            // I am the receiver
            inFinished = (flags & SpdyConnection.FLAG_FIN) != 0;
            outFinished = (flags & SpdyConnection.FLAG_UNIDIRECTIONAL) != 0;
        }
    }

    /**
     * Returns true if this stream was created by this peer.
     */
    public boolean isLocallyInitiated() {
        boolean streamIsClient = (id % 2 == 1);
        return connection.isClient() == streamIsClient;
    }

    public SpdyConnection getConnection() {
        return connection;
    }

    public List<String> getRequestHeaders() {
        return requestHeaders;
    }

    public synchronized List<String> getResponseHeaders() throws InterruptedException {
        while (responseHeaders == null && rstStatusCode == -1) {
            wait();
        }
        return responseHeaders;
    }

    /**
     * Returns the reason why this stream was closed, or -1 if it closed
     * normally or has not yet been closed.
     */
    public synchronized int getRstStatusCode() { // TODO: rename this?
        return rstStatusCode;
    }

    public InputStream getInputStream() {
        return in;
    }

    public OutputStream getOutputStream() {
        if (!isLocallyInitiated()) {
            throw new IllegalStateException("use reply for a remotely initiated stream");
        }
        return out;
    }

    /**
     * Sends a reply.
     */
    // TODO: support reply with FIN
    public synchronized OutputStream reply(List<String> responseHeaders) throws IOException {
        if (responseHeaders == null) {
            throw new NullPointerException("responseHeaders == null");
        }
        if (isLocallyInitiated()) {
            throw new IllegalStateException("cannot reply to a locally initiated stream");
        }
        synchronized (this) {
            if (this.responseHeaders != null) {
                throw new IllegalStateException("reply already sent");
            }
            this.responseHeaders = responseHeaders;
        }
        connection.writeSynReply(id, responseHeaders);
        return out;
    }

    /**
     * Abnormally terminate this stream.
     */
    public synchronized void close(int rstStatusCode) {
        // TODO: no-op if inFinished == true and outFinished == true ?
        if (this.rstStatusCode != -1) {
            this.rstStatusCode = rstStatusCode;
            inFinished = true;
            outFinished = true;
            connection.removeStream(id);
            notifyAll();
            connection.writeSynResetLater(id, rstStatusCode);
        }
    }

    synchronized void receiveReply(List<String> strings) throws IOException {
        if (!isLocallyInitiated() || responseHeaders != null) {
            throw new IOException(); // TODO: send RST
        }
        responseHeaders = strings;
        notifyAll();
    }

    synchronized void receiveData(InputStream in, int flags, int length) throws IOException {
        this.in.receive(in, length);
        if ((flags & SpdyConnection.FLAG_FIN) != 0) {
            inFinished = true;
            notifyAll();
        }
    }

    synchronized void receiveRstStream(int statusCode) {
        if (rstStatusCode != -1) {
            rstStatusCode = statusCode;
            inFinished = true;
            outFinished = true;
            notifyAll();
        }
    }

    /**
     * An input stream that reads the incoming data frames of a stream. Although
     * this class uses synchronization to safely receive incoming data frames,
     * it is not intended for use by multiple readers.
     */
    private final class SpdyDataInputStream extends InputStream {
        /*
         * Store incoming data bytes in a circular buffer. When the buffer is
         * empty, pos == -1. Otherwise pos is the first byte to read and limit
         * is the first byte to write.
         *
         * { - - - X X X X - - - }
         *         ^       ^
         *        pos    limit
         *
         * { X X X - - - - X X X }
         *         ^       ^
         *       limit    pos
         */

        private final byte[] buffer = new byte[64 * 1024]; // 64KiB specified by TODO
        /** the next byte to be read, or -1 if the buffer is empty. Never buffer.length */
        private int pos = -1;
        /** the last byte to be read. Never buffer.length */
        private int limit;
        /** True if the caller has closed this stream. */
        private boolean closed;

        @Override public int available() throws IOException {
            synchronized (SpdyStream.this) {
                checkNotClosed();
                if (pos == -1) {
                    return 0;
                } else if (limit > pos) {
                    return limit - pos;
                } else {
                    return limit + (buffer.length - pos);
                }
            }
        }

        @Override public int read() throws IOException {
            return Streams.readSingleByte(this);
        }

        @Override public int read(byte[] b, int offset, int count) throws IOException {
            synchronized (SpdyStream.this) {
                checkNotClosed();
                Libcore.checkOffsetAndCount(b.length, offset, count);

                while (pos == -1 && !inFinished) {
                    try {
                        SpdyStream.this.wait();
                    } catch (InterruptedException e) {
                        throw new InterruptedIOException();
                    }
                }

                if (pos == -1) {
                    return -1;
                }

                int copied = 0;

                // drain from [pos..buffer.length)
                if (limit <= pos) {
                    int bytesToCopy = Math.min(count, buffer.length - pos);
                    System.arraycopy(buffer, pos, b, offset, bytesToCopy);
                    pos += bytesToCopy;
                    copied += bytesToCopy;
                    if (pos == buffer.length) {
                        pos = 0;
                    }
                }

                // drain from [pos..limit)
                if (copied < count) {
                    int bytesToCopy = Math.min(limit - pos, count - copied);
                    System.arraycopy(buffer, pos, b, offset + copied, bytesToCopy);
                    pos += bytesToCopy;
                    copied += bytesToCopy;
                }

                // TODO: notify peer of flow-control

                if (pos == limit) {
                    pos = -1;
                    limit = 0;
                }

                return copied;
            }
        }

        void receive(InputStream in, int byteCount) throws IOException {
            if (inFinished) {
                return; // ignore this; probably a benign race
            }
            if (byteCount == 0) {
                return;
            }

            if (byteCount > buffer.length - available()) {
                throw new IOException(); // TODO: RST the stream
            }

            // fill [limit..buffer.length)
            if (pos < limit) {
                int firstCopyCount = Math.min(byteCount, buffer.length - limit);
                Streams.readFully(in, buffer, limit, firstCopyCount);
                limit += firstCopyCount;
                byteCount -= firstCopyCount;
                if (limit == buffer.length) {
                    limit = 0;
                }
            }

            // fill [limit..pos)
            if (byteCount > 0) {
                Streams.readFully(in, buffer, limit, byteCount);
                limit += byteCount;
            }

            if (pos == -1) {
                pos = 0;
                SpdyStream.this.notifyAll();
            }
        }

        @Override public void close() throws IOException {
            closed = true;
            // TODO: send RST to peer if !inFinished
        }

        private void checkNotClosed() throws IOException {
            if (closed) {
                throw new IOException("stream closed");
            }
        }
    }

    /**
     * An output stream that writes outgoing data frames of a stream. This class
     * is not thread safe.
     */
    private final class SpdyDataOutputStream extends OutputStream {
        private final byte[] buffer = new byte[8192];
        private int pos = DATA_FRAME_HEADER_LENGTH;

        /** True if the caller has closed this stream. */
        private boolean closed;

        @Override public void write(int b) throws IOException {
            Streams.writeSingleByte(this, b);
        }

        @Override public void write(byte[] bytes, int offset, int count) throws IOException {
            Libcore.checkOffsetAndCount(bytes.length, offset, count);
            checkNotClosed();

            while (count > 0) {
                if (pos == buffer.length) {
                    writeFrame(false);
                }
                int bytesToCopy = Math.min(count, buffer.length - pos);
                System.arraycopy(bytes, offset, buffer, pos, bytesToCopy);
                pos += bytesToCopy;
                offset += bytesToCopy;
                count -= bytesToCopy;
            }
        }

        @Override public void flush() throws IOException {
            checkNotClosed();
            if (pos > DATA_FRAME_HEADER_LENGTH) {
                writeFrame(false);
                connection.flush();
            }
        }

        @Override public void close() throws IOException {
            if (!closed) {
                closed = true;
                writeFrame(true);
                connection.flush();
            }
        }

        private void writeFrame(boolean last) throws IOException {
            int flags = 0;
            if (last) {
                flags |= SpdyConnection.FLAG_FIN;
            }
            int length = pos - DATA_FRAME_HEADER_LENGTH;
            Libcore.pokeInt(buffer, 0, id & 0x7fffffff, BIG_ENDIAN);
            Libcore.pokeInt(buffer, 4, (flags & 0xff) << 24 | length & 0xffffff, BIG_ENDIAN);
            connection.writeFrame(buffer, 0, pos);
            pos = DATA_FRAME_HEADER_LENGTH;
        }

        private void checkNotClosed() throws IOException {
            synchronized (SpdyStream.this) {
                if (closed) {
                    throw new IOException("stream closed");
                }
                if (outFinished) {
                    throw new IOException("output stream finished "
                            + "(RST status code=" + rstStatusCode + ")");
                }
            }
        }
    }
}

redpajama_set_name: RedPajamaGithub


A dermoscope is a microscope like device used by dermatologists to examine individual skin lesions more closely.
Dermoscopes offer diagnostic accuracy for diagnosing not only pigmented skin lesions and melanoma, but also a whole variety of dermatoses, including infections and inflammatory conditions.
Your consultant will use a small hand held microscope which is placed lightly against the skin. They will rub a fluid or gel on the instrument and your skin before it is used. The gel removes surface reflections from the skin and allows your consultant to see features and structures deep under the surface.


The Advanced RiderCourse (ARC) Provides a one-day 8-hour stress free, test free course that complements your basic skills and helps with personal risk assessment. You must be an Illinois resident 16 years of age or older. The course is beneficial for riders on any type of street motorcycle. You must have an "L" or "M" class motorcycle license, your own motorcycle and proof of insurance. The course may also earn you an insurance discount.


← What are the effects of entrepreneurial revolution and social media on the M&A industry?
This is my first M&A analysis in this blog. This time I will analyse the merger of London Stock Exchange (LSE) Group plc and TMX Group Inc. I will talk about the background of the deal briefly before giving my analysis of the transaction.
and the sales network from both firms will be combined so that they can distribute their products and services easier.
From my perspective, the merger between the two firms would benefit virtually all stakeholders from shareholders of both firms, governments of UK and Canada would benefit economically to users experiencing lower costs. As in all mergers and acquisitions transactions, some employees will lose their jobs and costs need to be reduced.
Comparison of offers that LSE Group plc could offer to purchase TMX Group Inc.
Note that the exchange rate between the British pound and the Canadian dollar on the day of the announcement (9/2/2011) is 1.60121. This rate is used to calculate the value of LSE Group's offer for TMX.
Looking at LSEs actual offer of 2.9963 LSE shares for each TMX share, equivalent of $42.25 per TMX share, the deal would overall represent good value for both LSE and TMX. If no synergies from the deal are achieved, LSE would lose a small value whereas TMX would lose significant proportion of its premium over the share price of $40.28 on 8/2/2011. The weighted average cost of capital (WACC) post-merger is 7.3%.
If LSE raised its offer to 3.1915 shares for each TMX share, $45 per TMX share, the deal would still represent a good value for both firms. However, LSE's return will be worse whereas TMX's has improved. If no synergies are achieved, than LSE would lose more value, in comparison to its actual offer, whereas TMX would still lose significant proportion of its premium. The premium at risk has increased slightly. From the post-market reaction analysis model, the post announcement premium at risk for TMX has fallen by almost 5%. The proportion of the merged company that TMX will own would increase to 46.7% whereas the proportion owned by LSE would decrease to 53.3%. WACC post-merger will fall to 7.2%.
If LSE matched any of the Maple Group's offers for TMX, the deal would not represent a good value for LSE as the costs of the deal would outweigh the benefits. It does obviously represent a good deal for TMX in either of Maple Group's offers. If LSE matched Maple Group's original offer of $48 per share than the former would end up losing about 8% of its value and make a loss of about the same amount if the stated synergies are not realised. The firm would end up losing about a 10% of its value and make a loss of 10% under the same situation if LSE matched Maple Group's revised offer of $50 per share. On the brighter side, the divergence between LSE and TMXs proportion of ownership will fall to 51.7% and 48.3% respectively, compared to the previous two deals mentioned earlier, if LSE matched Maple Group's original offer. If LSE offered $50 per share, the proportion of ownership between the two will be almost equal.
and still benefiting virtually all stakeholders in terms of the contributing to the growth of the UK and Canadian economies, higher profit margins for the combined firm, better provision of products and services and lower costs for users.
This entry was posted in M&A Analysis, Mergers and Acquisitions and tagged London Stock Exchange, London Stock Exchange Group plc, LSE, M&A, mergers and acquisitions, TMX, TMX Group, TMX Group Inc.. Bookmark the permalink.


Aug 20, 2015 - Football team kicks off Aug. 21.
Jul 22, 2015 - The tournament will feature eight teams in a double-elimination format.
Apr 03, 2015 - More than 2,500 players will make use of Kino's north and south complex.


Are you storing long or bulky items? This like new cantilever rack could be the perfect fit for your application then. This cantilever rack has both single-sided and double-sided bases available. Configurations can vary.