diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..6d7587a --- /dev/null +++ b/.classpath @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f2f2381 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*.{adoc,bat,groovy,html,java,js,jsp,kt,kts,md,properties,py,rb,sh,sql,svg,txt,xml,xsd}] +charset = utf-8 + +[*.{groovy,java,kt,kts,xml,xsd}] +indent_style = tab +indent_size = 4 +continuation_indent_size = 8 +end_of_line = lf \ No newline at end of file diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..56bb016 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip \ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 0000000..3919dfc --- /dev/null +++ b/.project @@ -0,0 +1,40 @@ + + + sse-eventbus-demo + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + org.springframework.ide.eclipse.core.springbuilder + + + + + org.springframework.ide.eclipse.boot.validation.springbootbuilder + + + + + + org.springframework.ide.eclipse.core.springnature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..abdea9a --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..714351a --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..d858295 --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ + + + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8dada3e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/mvnw b/mvnw new file mode 100644 index 0000000..6ecc150 --- /dev/null +++ b/mvnw @@ -0,0 +1,236 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # + # Look for the Apple JDKs first to preserve the existing behaviour, and then look + # for the new JDKs provided by Oracle. + # + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then + # + # Oracle JDKs + # + export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then + # + # Apple JDKs + # + export JAVA_HOME=`/usr/libexec/java_home` + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Migwn, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + local basedir=$(pwd) + local wdir=$(pwd) + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + wdir=$(cd "$wdir/.."; pwd) + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +# avoid using MAVEN_CMD_LINE_ARGS below since that would loose parameter escaping in $@ +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..8bb8275 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,146 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %* + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" + +set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +# avoid using MAVEN_CMD_LINE_ARGS below since that would loose parameter escaping in %* +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..6ffc2e5 --- /dev/null +++ b/pom.xml @@ -0,0 +1,88 @@ + + + 4.0.0 + + ch.rasc + sse-eventbus-demo + 1.1.0 + jar + + sse-eventbus-demo + Demo project for sse-eventbus library + + + + Faiz Akram + faiz.krm@gmail.com + + + + + + Apache 2 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + GitHub + https://github.com/ralscha/sse-eventbus-demo/issues + + + + scm:git:git@github.com:ralscha/sse-eventbus-demo.git + scm:git:git@github.com:ralscha/sse-eventbus-demo.git + https://github.com/ralscha/sse-eventbus-demo.git + + + + org.springframework.boot + spring-boot-starter-parent + 1.5.8.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + org.springframework.boot + spring-boot-starter-undertow + + + + ch.rasc + sse-eventbus + 1.1.3 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/src/main/java/ch/rasc/Application.java b/src/main/java/ch/rasc/Application.java new file mode 100644 index 0000000..7a181b5 --- /dev/null +++ b/src/main/java/ch/rasc/Application.java @@ -0,0 +1,17 @@ +package ch.rasc; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; + +import ch.rasc.sse.eventbus.config.EnableSseEventBus; + +@SpringBootApplication +@EnableScheduling +@EnableSseEventBus +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/src/main/java/ch/rasc/DataEmitterService.java b/src/main/java/ch/rasc/DataEmitterService.java new file mode 100644 index 0000000..7b0ca12 --- /dev/null +++ b/src/main/java/ch/rasc/DataEmitterService.java @@ -0,0 +1,66 @@ +package ch.rasc; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import ch.rasc.sse.eventbus.SseEvent; +import ch.rasc.sse.eventbus.SseEvent.Builder; + +@Service +public class DataEmitterService { + + private final ApplicationEventPublisher eventPublisher; + // OR: private final ApplicationContext ctx; + // this class implements the ApplicationEventPublisher interface + private List list = new ArrayList(); + + //private final static Random random = new Random(); + + public DataEmitterService(ApplicationEventPublisher eventPublisher) { + this.eventPublisher = eventPublisher; + } + + public void addListInfo(String id) + { + list.add(id); + } + + + + + @Scheduled(initialDelay = 2000, fixedRate = 5_000) + public void sendData() { + /* + * System.out.println("Send Data"); + StringBuilder sb = new StringBuilder("["); + for (int i = 0; i < 5; i++) { + sb.append(random.nextInt(31)); + sb.append(","); + } + sb.replace(sb.length() - 1, sb.length(), "]"); +*/ + for(String str:list) { + + if(list.indexOf(str) == 0) + { + Builder builder1 = new SseEvent.Builder(); + Builder builder = builder1.from(SseEvent.ofData("Delhi")); + builder.addClientId(str); + this.eventPublisher.publishEvent(builder.build()); + } + else + { + Builder builder1 = new SseEvent.Builder(); + Builder builder = builder1.from(SseEvent.ofData("Goa")); + builder.addClientId(str); + this.eventPublisher.publishEvent(builder.build()); + } + } + + } + +} diff --git a/src/main/java/ch/rasc/SseController.java b/src/main/java/ch/rasc/SseController.java new file mode 100644 index 0000000..2723b3e --- /dev/null +++ b/src/main/java/ch/rasc/SseController.java @@ -0,0 +1,46 @@ +package ch.rasc; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import ch.rasc.sse.eventbus.SseEvent; +import ch.rasc.sse.eventbus.SseEventBus; +@CrossOrigin +@Controller +public class SseController { + + private final SseEventBus eventBus; + + + @Autowired + private DataEmitterService dataEmitterService; + + public SseController(SseEventBus eventBus) { + this.eventBus = eventBus; + } + + //@GetMapping("/register/{id}") + @RequestMapping(value = "/register/{id}",method = RequestMethod.GET) + public SseEmitter register(@PathVariable("id") String id, @RequestHeader(value = "User-Agent") String userAgent) { + //System.out.println("id ==== " + id); + dataEmitterService.addListInfo(id); + if (userAgent.contains("Edge/")) { + // Use long polling instead of streaming + // Create an emitter that closes the connection after sending each message + // this is a workaround for the Microsoft Edge browser + return this.eventBus.createSseEmitter(id, 180_000L, false, true, SseEvent.DEFAULT_EVENT); + } + //this.eventBus.setDataObjectConverters(dataObjectConverters); + //return this.eventBus.createSseEmitter(id, events); + return this.eventBus.createSseEmitter(id, SseEvent.DEFAULT_EVENT); + } + + + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/static/app.js b/src/main/resources/static/app.js new file mode 100644 index 0000000..608a0c8 --- /dev/null +++ b/src/main/resources/static/app.js @@ -0,0 +1,97 @@ +function getChartOption(name, threshold) { + return { + series: [ { + startAngle: 180, + endAngle: 0, + center: [ '50%', '90%' ], + radius: 100, + min: 0, + max: 30, + name: 'Serie', + type: 'gauge', + splitNumber: 3, + data: [ { + value: 16, + name: name + } ], + title: { + show: true, + offsetCenter: [ '-100%', '-90%' ], + textStyle: { + color: '#333', + fontSize: 15 + } + }, + axisLine: { + lineStyle: { + color: [ [ threshold, '#ff4500' ], [ 1, 'lightgreen' ] ], + width: 8 + } + }, + axisTick: { + length: 11, + lineStyle: { + color: 'auto' + } + }, + splitLine: { + length: 15, + lineStyle: { + color: 'auto' + } + }, + detail: { + show: true, + offsetCenter: [ '100%', '-100%' ], + textStyle: { + color: 'auto', + fontSize: 25 + } + } + + } ] + + }; +} + +var names = ['s1', 's2', 's3', 's4', 's5']; +var threshold = [0.1, 0.2, 0.7, 0.5, 0.9]; +var gauges = []; + +for (let i = 0; i < names.length; i++) { + var chart = echarts.init(document.getElementById('chart'+(i+1))); + chart.setOption(getChartOption(names[i], threshold[i])); + gauges.push(chart); +} + +var uuid = uuid.v4(); + +var eventSource; + +window.onbeforeunload = () => { + if (eventSource) { + eventSource.close(); + } +} + +eventSource = new EventSource(`/register/${uuid}`); +eventSource.addEventListener('message', response => { + console.log(response.data); + /*for (let line of response.data.split('\n')) { + console.log(line); + handleResponse(JSON.parse(line)); + }*/ +}, false); + +function handleResponse(data) { + for (let i = 0; i < 5; i++) { + gauges[i].setOption({ + series: { + data: [ { + name: names[i], + value: data[i] + } ] + } + }); + } +} diff --git a/src/main/resources/static/appes5.js b/src/main/resources/static/appes5.js new file mode 100644 index 0000000..f59fbd3 --- /dev/null +++ b/src/main/resources/static/appes5.js @@ -0,0 +1,117 @@ +'use strict'; + +function getChartOption(name, threshold) { + return { + series: [{ + startAngle: 180, + endAngle: 0, + center: ['50%', '90%'], + radius: 100, + min: 0, + max: 30, + name: 'Serie', + type: 'gauge', + splitNumber: 3, + data: [{ + value: 16, + name: name + }], + title: { + show: true, + offsetCenter: ['-100%', '-90%'], + textStyle: { + color: '#333', + fontSize: 15 + } + }, + axisLine: { + lineStyle: { + color: [[threshold, '#ff4500'], [1, 'lightgreen']], + width: 8 + } + }, + axisTick: { + length: 11, + lineStyle: { + color: 'auto' + } + }, + splitLine: { + length: 15, + lineStyle: { + color: 'auto' + } + }, + detail: { + show: true, + offsetCenter: ['100%', '-100%'], + textStyle: { + color: 'auto', + fontSize: 25 + } + } + + }] + + }; +} + +var names = ['s1', 's2', 's3', 's4', 's5']; +var threshold = [0.1, 0.2, 0.7, 0.5, 0.9]; +var gauges = []; + +for (var i = 0; i < names.length; i++) { + var chart = echarts.init(document.getElementById('chart' + (i + 1))); + chart.setOption(getChartOption(names[i], threshold[i])); + gauges.push(chart); +} + +var uuid = uuid.v4(); +var eventSource; + +window.onbeforeunload = function () { + if (eventSource) { + eventSource.close(); + } +}; + +eventSource = new EventSource('/register/' + uuid); +eventSource.addEventListener('message', function (response) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = response.data.split('\n')[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var line = _step.value; + + handleResponse(JSON.parse(line)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } +}, false); + +function handleResponse(data) { + for (var _i = 0; _i < 5; _i++) { + gauges[_i].setOption({ + series: { + data: [{ + name: names[_i], + value: data[_i] + }] + } + }); + } +} \ No newline at end of file diff --git a/src/main/resources/static/eventsource.js b/src/main/resources/static/eventsource.js new file mode 100644 index 0000000..4d6ef77 --- /dev/null +++ b/src/main/resources/static/eventsource.js @@ -0,0 +1,6 @@ +/** @license + * eventsource.js + * Available under MIT License (MIT) + * https://github.com/Yaffle/EventSource/ + */ +!function(a){"use strict";function b(){this.data={}}function c(){this.listeners=new b}function d(a){k(function(){throw a},0)}function e(a){this.type=a,this.target=void 0}function f(a,b){e.call(this,a),this.data=b.data,this.lastEventId=b.lastEventId}function g(a,b){var c=a;return c!==c&&(c=b),A>c?A:c>B?B:c}function h(a,b,c){try{"function"==typeof b&&b.call(a,c)}catch(e){d(e)}}function i(b,d){function i(){P=t,void 0!=L&&(L.abort(),L=void 0),0!==M&&(l(M),M=0),0!==N&&(l(N),N=0),H.readyState=t}function j(a){var c="";if(P===s||P===r)try{c=L.responseText}catch(d){}var j=void 0,m=!1;if(P===r){var n=0,o="",p=void 0;if("contentType"in L)""!==a&&"error"!==a&&(n=200,o="OK",p=L.contentType);else try{n=L.status,o=L.statusText,p=L.getResponseHeader("Content-Type")}catch(d){n=0,o="",p=void 0}if(void 0==p&&(p=""),0===n&&""===o&&"load"===a&&""!==c&&(n=200,o="OK",""===p)){var A=/^data\:([^,]*?)(?:;base64)?,[\S]*$/.exec(b);void 0!=A&&(p=A[1])}if(200===n&&z.test(p)){if(P=s,J=!0,I=E,H.readyState=s,j=new e("open"),H.dispatchEvent(j),h(H,H.onopen,j),P===t)return}else if(0!==n&&(200!==n||""!==p)){var C="";C=200!==n?"EventSource's response has a status "+n+" "+o.replace(/\s+/g," ")+" that is not 200. Aborting the connection.":"EventSource's response has a Content-Type specifying an unsupported type: "+p.replace(/\s+/g," ")+". Aborting the connection.",k(function(){throw new Error(C)},0),m=!0}}if(P===s){c.length>O&&(J=!0);for(var D=O-1,K=c.length,N="\n";++D1048576||0===M&&!J)?0===M&&(J=!1,M=k(T,F)):(m?i():(""!==a||0!==M||J||k(function(){throw new Error("No activity within "+F+" milliseconds. Reconnecting.")},0),P=q,L.abort(),0!==M&&(l(M),M=0),I>16*E&&(I=16*E),I>B&&(I=B),M=k(T,I),I=2*I+1,H.readyState=r),j=new e("error"),H.dispatchEvent(j),h(H,H.onerror,j))}function m(){j("progress")}function n(){j("load")}function A(){j("error")}function C(){j(4===L.readyState?0===L.status?"error":"load":"progress")}b=b.toString();var D=o&&void 0!=d&&Boolean(d.withCredentials),E=g(1e3,0),F=g(45e3,0),G="",H=this,I=E,J=!1,K=void 0!=d&&void 0!=d.Transport?d.Transport:p,L=new K,M=0,N=0,O=0,P=q,Q=[],R="",S="",T=void 0,U=v,V="",W="";"readyState"in L&&void 0!=a.opera&&(N=k(function X(){3===L.readyState&&j("progress"),N=k(X,500)},0)),T=function(){if(M=0,P!==q)return void j("");if((!("ontimeout"in L)||"sendAsBinary"in L||"mozAnon"in L)&&void 0!=a.document&&void 0!=a.document.readyState&&"complete"!==a.document.readyState)return void(M=k(T,4));L.onload=n,L.onerror=A,"onabort"in L&&(L.onabort=A),"onprogress"in L&&(L.onprogress=m),"onreadystatechange"in L&&(L.onreadystatechange=C),J=!1,M=k(T,F),O=0,P=r,Q.length=0,S="",R=G,W="",V="",U=v;var c=b.slice(0,5);c="data:"!==c&&"blob:"!==c?b+((-1===b.indexOf("?",0)?"?":"&")+"lastEventId="+encodeURIComponent(G)+"&r="+(Math.random()+1).toString().slice(2)):b,L.open("GET",c,!0),"withCredentials"in L&&(L.withCredentials=D),"responseType"in L&&(L.responseType="text"),"setRequestHeader"in L&&L.setRequestHeader("Accept","text/event-stream"),L.send(void 0)},c.call(this),this.close=i,this.url=b,this.readyState=r,this.withCredentials=D,this.onopen=void 0,this.onmessage=void 0,this.onerror=void 0,T()}function j(){this.CONNECTING=r,this.OPEN=s,this.CLOSED=t}var k=a.setTimeout,l=a.clearTimeout;b.prototype.get=function(a){return this.data[a+"~"]},b.prototype.set=function(a,b){this.data[a+"~"]=b},b.prototype["delete"]=function(a){delete this.data[a+"~"]},c.prototype.dispatchEvent=function(a){a.target=this;var b=a.type.toString(),c=this.listeners,e=c.get(b);if(void 0!=e)for(var f=e.length,g=-1,h=void 0;++g=0;)if(d[e]===b)return;d.push(b)},c.prototype.removeEventListener=function(a,b){a=a.toString();var c=this.listeners,d=c.get(a);if(void 0!=d){for(var e=d.length,f=[],g=-1;++g + + +sse-eventbus-demo with echarts + + + + + +
+
+
+
+
+ + + + + + + + diff --git a/src/main/resources/static/indexes5.html b/src/main/resources/static/indexes5.html new file mode 100644 index 0000000..e881c1a --- /dev/null +++ b/src/main/resources/static/indexes5.html @@ -0,0 +1,31 @@ + + + +sse-eventbus-demo with echarts + + + + + +
+
+
+
+
+ + + + + + + + + diff --git a/src/main/resources/static/uuid.js b/src/main/resources/static/uuid.js new file mode 100644 index 0000000..89cf257 --- /dev/null +++ b/src/main/resources/static/uuid.js @@ -0,0 +1,272 @@ +// uuid.js +// +// Copyright (c) 2010-2012 Robert Kieffer +// MIT License - http://opensource.org/licenses/mit-license.php + +/*global window, require, define */ +(function(_window) { + 'use strict'; + + // Unique ID creation requires a high quality random # generator. We feature + // detect to determine the best RNG source, normalizing to a function that + // returns 128-bits of randomness, since that's what's usually required + var _rng, _mathRNG, _nodeRNG, _whatwgRNG, _previousRoot; + + function setupBrowser() { + // Allow for MSIE11 msCrypto + var _crypto = _window.crypto || _window.msCrypto; + + if (!_rng && _crypto && _crypto.getRandomValues) { + // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto + // + // Moderately fast, high quality + try { + var _rnds8 = new Uint8Array(16); + _whatwgRNG = _rng = function whatwgRNG() { + _crypto.getRandomValues(_rnds8); + return _rnds8; + }; + _rng(); + } catch(e) {} + } + + if (!_rng) { + // Math.random()-based (RNG) + // + // If all else fails, use Math.random(). It's fast, but is of unspecified + // quality. + var _rnds = new Array(16); + _mathRNG = _rng = function() { + for (var i = 0, r; i < 16; i++) { + if ((i & 0x03) === 0) { r = Math.random() * 0x100000000; } + _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; + } + + return _rnds; + }; + if ('undefined' !== typeof console && console.warn) { + console.warn("[SECURITY] node-uuid: crypto not usable, falling back to insecure Math.random()"); + } + } + } + + function setupNode() { + // Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html + // + // Moderately fast, high quality + if ('function' === typeof require) { + try { + var _rb = require('crypto').randomBytes; + _nodeRNG = _rng = _rb && function() {return _rb(16);}; + _rng(); + } catch(e) {} + } + } + + if (_window) { + setupBrowser(); + } else { + setupNode(); + } + + // Buffer class to use + var BufferClass = ('function' === typeof Buffer) ? Buffer : Array; + + // Maps for number <-> hex string conversion + var _byteToHex = []; + var _hexToByte = {}; + for (var i = 0; i < 256; i++) { + _byteToHex[i] = (i + 0x100).toString(16).substr(1); + _hexToByte[_byteToHex[i]] = i; + } + + // **`parse()` - Parse a UUID into it's component bytes** + function parse(s, buf, offset) { + var i = (buf && offset) || 0, ii = 0; + + buf = buf || []; + s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) { + if (ii < 16) { // Don't overflow! + buf[i + ii++] = _hexToByte[oct]; + } + }); + + // Zero out remaining bytes if string was short + while (ii < 16) { + buf[i + ii++] = 0; + } + + return buf; + } + + // **`unparse()` - Convert UUID byte array (ala parse()) into a string** + function unparse(buf, offset) { + var i = offset || 0, bth = _byteToHex; + return bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]]; + } + + // **`v1()` - Generate time-based UUID** + // + // Inspired by https://github.com/LiosK/UUID.js + // and http://docs.python.org/library/uuid.html + + // random #'s we need to init node and clockseq + var _seedBytes = _rng(); + + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + var _nodeId = [ + _seedBytes[0] | 0x01, + _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5] + ]; + + // Per 4.2.2, randomize (14 bit) clockseq + var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff; + + // Previous uuid creation time + var _lastMSecs = 0, _lastNSecs = 0; + + // See https://github.com/broofa/node-uuid for API details + function v1(options, buf, offset) { + var i = buf && offset || 0; + var b = buf || []; + + options = options || {}; + + var clockseq = (options.clockseq != null) ? options.clockseq : _clockseq; + + // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + var msecs = (options.msecs != null) ? options.msecs : new Date().getTime(); + + // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + var nsecs = (options.nsecs != null) ? options.nsecs : _lastNSecs + 1; + + // Time since last uuid creation (in msecs) + var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; + + // Per 4.2.1.2, Bump clockseq on clock regression + if (dt < 0 && options.clockseq == null) { + clockseq = clockseq + 1 & 0x3fff; + } + + // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) { + nsecs = 0; + } + + // Per 4.2.1.2 Throw error if too many uuids are requested + if (nsecs >= 10000) { + throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + + // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + msecs += 12219292800000; + + // `time_low` + var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; + + // `time_mid` + var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; + + // `time_high_and_version` + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + b[i++] = tmh >>> 16 & 0xff; + + // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + b[i++] = clockseq >>> 8 | 0x80; + + // `clock_seq_low` + b[i++] = clockseq & 0xff; + + // `node` + var node = options.node || _nodeId; + for (var n = 0; n < 6; n++) { + b[i + n] = node[n]; + } + + return buf ? buf : unparse(b); + } + + // **`v4()` - Generate random UUID** + + // See https://github.com/broofa/node-uuid for API details + function v4(options, buf, offset) { + // Deprecated - 'format' argument, as supported in v1.2 + var i = buf && offset || 0; + + if (typeof(options) === 'string') { + buf = (options === 'binary') ? new BufferClass(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || _rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ii++) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || unparse(rnds); + } + + // Export public API + var uuid = v4; + uuid.v1 = v1; + uuid.v4 = v4; + uuid.parse = parse; + uuid.unparse = unparse; + uuid.BufferClass = BufferClass; + uuid._rng = _rng; + uuid._mathRNG = _mathRNG; + uuid._nodeRNG = _nodeRNG; + uuid._whatwgRNG = _whatwgRNG; + + if (('undefined' !== typeof module) && module.exports) { + // Publish as node.js module + module.exports = uuid; + } else if (typeof define === 'function' && define.amd) { + // Publish as AMD module + define(function() {return uuid;}); + + + } else { + // Publish as global (in browsers) + _previousRoot = _window.uuid; + + // **`noConflict()` - (browser only) to reset global 'uuid' var** + uuid.noConflict = function() { + _window.uuid = _previousRoot; + return uuid; + }; + + _window.uuid = uuid; + } +})('undefined' !== typeof window ? window : null); \ No newline at end of file diff --git a/target/classes/META-INF/MANIFEST.MF b/target/classes/META-INF/MANIFEST.MF new file mode 100644 index 0000000..675072b --- /dev/null +++ b/target/classes/META-INF/MANIFEST.MF @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Implementation-Title: sse-eventbus-demo +Implementation-Version: 1.1.0 +Built-By: 13615 +Implementation-Vendor-Id: ch.rasc +Build-Jdk: 1.8.0_91 +Implementation-URL: http://projects.spring.io/spring-boot/sse-eventbus + -demo/ +Created-By: Maven Integration for Eclipse +Implementation-Vendor: Pivotal Software, Inc. + diff --git a/target/classes/META-INF/maven/ch.rasc/sse-eventbus-demo/pom.properties b/target/classes/META-INF/maven/ch.rasc/sse-eventbus-demo/pom.properties new file mode 100644 index 0000000..e1d7213 --- /dev/null +++ b/target/classes/META-INF/maven/ch.rasc/sse-eventbus-demo/pom.properties @@ -0,0 +1,7 @@ +#Generated by Maven Integration for Eclipse +#Thu Nov 09 18:38:16 IST 2017 +version=1.1.0 +groupId=ch.rasc +m2e.projectName=sse-eventbus-demo +m2e.projectLocation=C\:\\Users\\13615\\Downloads\\sse-eventbus-demo-master\\sse-eventbus-demo-master +artifactId=sse-eventbus-demo diff --git a/target/classes/META-INF/maven/ch.rasc/sse-eventbus-demo/pom.xml b/target/classes/META-INF/maven/ch.rasc/sse-eventbus-demo/pom.xml new file mode 100644 index 0000000..6ffc2e5 --- /dev/null +++ b/target/classes/META-INF/maven/ch.rasc/sse-eventbus-demo/pom.xml @@ -0,0 +1,88 @@ + + + 4.0.0 + + ch.rasc + sse-eventbus-demo + 1.1.0 + jar + + sse-eventbus-demo + Demo project for sse-eventbus library + + + + Faiz Akram + faiz.krm@gmail.com + + + + + + Apache 2 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + GitHub + https://github.com/ralscha/sse-eventbus-demo/issues + + + + scm:git:git@github.com:ralscha/sse-eventbus-demo.git + scm:git:git@github.com:ralscha/sse-eventbus-demo.git + https://github.com/ralscha/sse-eventbus-demo.git + + + + org.springframework.boot + spring-boot-starter-parent + 1.5.8.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + org.springframework.boot + spring-boot-starter-undertow + + + + ch.rasc + sse-eventbus + 1.1.3 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/target/classes/application.properties b/target/classes/application.properties new file mode 100644 index 0000000..e69de29 diff --git a/target/classes/static/app.js b/target/classes/static/app.js new file mode 100644 index 0000000..608a0c8 --- /dev/null +++ b/target/classes/static/app.js @@ -0,0 +1,97 @@ +function getChartOption(name, threshold) { + return { + series: [ { + startAngle: 180, + endAngle: 0, + center: [ '50%', '90%' ], + radius: 100, + min: 0, + max: 30, + name: 'Serie', + type: 'gauge', + splitNumber: 3, + data: [ { + value: 16, + name: name + } ], + title: { + show: true, + offsetCenter: [ '-100%', '-90%' ], + textStyle: { + color: '#333', + fontSize: 15 + } + }, + axisLine: { + lineStyle: { + color: [ [ threshold, '#ff4500' ], [ 1, 'lightgreen' ] ], + width: 8 + } + }, + axisTick: { + length: 11, + lineStyle: { + color: 'auto' + } + }, + splitLine: { + length: 15, + lineStyle: { + color: 'auto' + } + }, + detail: { + show: true, + offsetCenter: [ '100%', '-100%' ], + textStyle: { + color: 'auto', + fontSize: 25 + } + } + + } ] + + }; +} + +var names = ['s1', 's2', 's3', 's4', 's5']; +var threshold = [0.1, 0.2, 0.7, 0.5, 0.9]; +var gauges = []; + +for (let i = 0; i < names.length; i++) { + var chart = echarts.init(document.getElementById('chart'+(i+1))); + chart.setOption(getChartOption(names[i], threshold[i])); + gauges.push(chart); +} + +var uuid = uuid.v4(); + +var eventSource; + +window.onbeforeunload = () => { + if (eventSource) { + eventSource.close(); + } +} + +eventSource = new EventSource(`/register/${uuid}`); +eventSource.addEventListener('message', response => { + console.log(response.data); + /*for (let line of response.data.split('\n')) { + console.log(line); + handleResponse(JSON.parse(line)); + }*/ +}, false); + +function handleResponse(data) { + for (let i = 0; i < 5; i++) { + gauges[i].setOption({ + series: { + data: [ { + name: names[i], + value: data[i] + } ] + } + }); + } +} diff --git a/target/classes/static/appes5.js b/target/classes/static/appes5.js new file mode 100644 index 0000000..f59fbd3 --- /dev/null +++ b/target/classes/static/appes5.js @@ -0,0 +1,117 @@ +'use strict'; + +function getChartOption(name, threshold) { + return { + series: [{ + startAngle: 180, + endAngle: 0, + center: ['50%', '90%'], + radius: 100, + min: 0, + max: 30, + name: 'Serie', + type: 'gauge', + splitNumber: 3, + data: [{ + value: 16, + name: name + }], + title: { + show: true, + offsetCenter: ['-100%', '-90%'], + textStyle: { + color: '#333', + fontSize: 15 + } + }, + axisLine: { + lineStyle: { + color: [[threshold, '#ff4500'], [1, 'lightgreen']], + width: 8 + } + }, + axisTick: { + length: 11, + lineStyle: { + color: 'auto' + } + }, + splitLine: { + length: 15, + lineStyle: { + color: 'auto' + } + }, + detail: { + show: true, + offsetCenter: ['100%', '-100%'], + textStyle: { + color: 'auto', + fontSize: 25 + } + } + + }] + + }; +} + +var names = ['s1', 's2', 's3', 's4', 's5']; +var threshold = [0.1, 0.2, 0.7, 0.5, 0.9]; +var gauges = []; + +for (var i = 0; i < names.length; i++) { + var chart = echarts.init(document.getElementById('chart' + (i + 1))); + chart.setOption(getChartOption(names[i], threshold[i])); + gauges.push(chart); +} + +var uuid = uuid.v4(); +var eventSource; + +window.onbeforeunload = function () { + if (eventSource) { + eventSource.close(); + } +}; + +eventSource = new EventSource('/register/' + uuid); +eventSource.addEventListener('message', function (response) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = response.data.split('\n')[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var line = _step.value; + + handleResponse(JSON.parse(line)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } +}, false); + +function handleResponse(data) { + for (var _i = 0; _i < 5; _i++) { + gauges[_i].setOption({ + series: { + data: [{ + name: names[_i], + value: data[_i] + }] + } + }); + } +} \ No newline at end of file diff --git a/target/classes/static/eventsource.js b/target/classes/static/eventsource.js new file mode 100644 index 0000000..4d6ef77 --- /dev/null +++ b/target/classes/static/eventsource.js @@ -0,0 +1,6 @@ +/** @license + * eventsource.js + * Available under MIT License (MIT) + * https://github.com/Yaffle/EventSource/ + */ +!function(a){"use strict";function b(){this.data={}}function c(){this.listeners=new b}function d(a){k(function(){throw a},0)}function e(a){this.type=a,this.target=void 0}function f(a,b){e.call(this,a),this.data=b.data,this.lastEventId=b.lastEventId}function g(a,b){var c=a;return c!==c&&(c=b),A>c?A:c>B?B:c}function h(a,b,c){try{"function"==typeof b&&b.call(a,c)}catch(e){d(e)}}function i(b,d){function i(){P=t,void 0!=L&&(L.abort(),L=void 0),0!==M&&(l(M),M=0),0!==N&&(l(N),N=0),H.readyState=t}function j(a){var c="";if(P===s||P===r)try{c=L.responseText}catch(d){}var j=void 0,m=!1;if(P===r){var n=0,o="",p=void 0;if("contentType"in L)""!==a&&"error"!==a&&(n=200,o="OK",p=L.contentType);else try{n=L.status,o=L.statusText,p=L.getResponseHeader("Content-Type")}catch(d){n=0,o="",p=void 0}if(void 0==p&&(p=""),0===n&&""===o&&"load"===a&&""!==c&&(n=200,o="OK",""===p)){var A=/^data\:([^,]*?)(?:;base64)?,[\S]*$/.exec(b);void 0!=A&&(p=A[1])}if(200===n&&z.test(p)){if(P=s,J=!0,I=E,H.readyState=s,j=new e("open"),H.dispatchEvent(j),h(H,H.onopen,j),P===t)return}else if(0!==n&&(200!==n||""!==p)){var C="";C=200!==n?"EventSource's response has a status "+n+" "+o.replace(/\s+/g," ")+" that is not 200. Aborting the connection.":"EventSource's response has a Content-Type specifying an unsupported type: "+p.replace(/\s+/g," ")+". Aborting the connection.",k(function(){throw new Error(C)},0),m=!0}}if(P===s){c.length>O&&(J=!0);for(var D=O-1,K=c.length,N="\n";++D1048576||0===M&&!J)?0===M&&(J=!1,M=k(T,F)):(m?i():(""!==a||0!==M||J||k(function(){throw new Error("No activity within "+F+" milliseconds. Reconnecting.")},0),P=q,L.abort(),0!==M&&(l(M),M=0),I>16*E&&(I=16*E),I>B&&(I=B),M=k(T,I),I=2*I+1,H.readyState=r),j=new e("error"),H.dispatchEvent(j),h(H,H.onerror,j))}function m(){j("progress")}function n(){j("load")}function A(){j("error")}function C(){j(4===L.readyState?0===L.status?"error":"load":"progress")}b=b.toString();var D=o&&void 0!=d&&Boolean(d.withCredentials),E=g(1e3,0),F=g(45e3,0),G="",H=this,I=E,J=!1,K=void 0!=d&&void 0!=d.Transport?d.Transport:p,L=new K,M=0,N=0,O=0,P=q,Q=[],R="",S="",T=void 0,U=v,V="",W="";"readyState"in L&&void 0!=a.opera&&(N=k(function X(){3===L.readyState&&j("progress"),N=k(X,500)},0)),T=function(){if(M=0,P!==q)return void j("");if((!("ontimeout"in L)||"sendAsBinary"in L||"mozAnon"in L)&&void 0!=a.document&&void 0!=a.document.readyState&&"complete"!==a.document.readyState)return void(M=k(T,4));L.onload=n,L.onerror=A,"onabort"in L&&(L.onabort=A),"onprogress"in L&&(L.onprogress=m),"onreadystatechange"in L&&(L.onreadystatechange=C),J=!1,M=k(T,F),O=0,P=r,Q.length=0,S="",R=G,W="",V="",U=v;var c=b.slice(0,5);c="data:"!==c&&"blob:"!==c?b+((-1===b.indexOf("?",0)?"?":"&")+"lastEventId="+encodeURIComponent(G)+"&r="+(Math.random()+1).toString().slice(2)):b,L.open("GET",c,!0),"withCredentials"in L&&(L.withCredentials=D),"responseType"in L&&(L.responseType="text"),"setRequestHeader"in L&&L.setRequestHeader("Accept","text/event-stream"),L.send(void 0)},c.call(this),this.close=i,this.url=b,this.readyState=r,this.withCredentials=D,this.onopen=void 0,this.onmessage=void 0,this.onerror=void 0,T()}function j(){this.CONNECTING=r,this.OPEN=s,this.CLOSED=t}var k=a.setTimeout,l=a.clearTimeout;b.prototype.get=function(a){return this.data[a+"~"]},b.prototype.set=function(a,b){this.data[a+"~"]=b},b.prototype["delete"]=function(a){delete this.data[a+"~"]},c.prototype.dispatchEvent=function(a){a.target=this;var b=a.type.toString(),c=this.listeners,e=c.get(b);if(void 0!=e)for(var f=e.length,g=-1,h=void 0;++g=0;)if(d[e]===b)return;d.push(b)},c.prototype.removeEventListener=function(a,b){a=a.toString();var c=this.listeners,d=c.get(a);if(void 0!=d){for(var e=d.length,f=[],g=-1;++g + + +sse-eventbus-demo with echarts + + + + + +
+
+
+
+
+ + + + + + + + diff --git a/target/classes/static/indexes5.html b/target/classes/static/indexes5.html new file mode 100644 index 0000000..e881c1a --- /dev/null +++ b/target/classes/static/indexes5.html @@ -0,0 +1,31 @@ + + + +sse-eventbus-demo with echarts + + + + + +
+
+
+
+
+ + + + + + + + + diff --git a/target/classes/static/uuid.js b/target/classes/static/uuid.js new file mode 100644 index 0000000..89cf257 --- /dev/null +++ b/target/classes/static/uuid.js @@ -0,0 +1,272 @@ +// uuid.js +// +// Copyright (c) 2010-2012 Robert Kieffer +// MIT License - http://opensource.org/licenses/mit-license.php + +/*global window, require, define */ +(function(_window) { + 'use strict'; + + // Unique ID creation requires a high quality random # generator. We feature + // detect to determine the best RNG source, normalizing to a function that + // returns 128-bits of randomness, since that's what's usually required + var _rng, _mathRNG, _nodeRNG, _whatwgRNG, _previousRoot; + + function setupBrowser() { + // Allow for MSIE11 msCrypto + var _crypto = _window.crypto || _window.msCrypto; + + if (!_rng && _crypto && _crypto.getRandomValues) { + // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto + // + // Moderately fast, high quality + try { + var _rnds8 = new Uint8Array(16); + _whatwgRNG = _rng = function whatwgRNG() { + _crypto.getRandomValues(_rnds8); + return _rnds8; + }; + _rng(); + } catch(e) {} + } + + if (!_rng) { + // Math.random()-based (RNG) + // + // If all else fails, use Math.random(). It's fast, but is of unspecified + // quality. + var _rnds = new Array(16); + _mathRNG = _rng = function() { + for (var i = 0, r; i < 16; i++) { + if ((i & 0x03) === 0) { r = Math.random() * 0x100000000; } + _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; + } + + return _rnds; + }; + if ('undefined' !== typeof console && console.warn) { + console.warn("[SECURITY] node-uuid: crypto not usable, falling back to insecure Math.random()"); + } + } + } + + function setupNode() { + // Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html + // + // Moderately fast, high quality + if ('function' === typeof require) { + try { + var _rb = require('crypto').randomBytes; + _nodeRNG = _rng = _rb && function() {return _rb(16);}; + _rng(); + } catch(e) {} + } + } + + if (_window) { + setupBrowser(); + } else { + setupNode(); + } + + // Buffer class to use + var BufferClass = ('function' === typeof Buffer) ? Buffer : Array; + + // Maps for number <-> hex string conversion + var _byteToHex = []; + var _hexToByte = {}; + for (var i = 0; i < 256; i++) { + _byteToHex[i] = (i + 0x100).toString(16).substr(1); + _hexToByte[_byteToHex[i]] = i; + } + + // **`parse()` - Parse a UUID into it's component bytes** + function parse(s, buf, offset) { + var i = (buf && offset) || 0, ii = 0; + + buf = buf || []; + s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) { + if (ii < 16) { // Don't overflow! + buf[i + ii++] = _hexToByte[oct]; + } + }); + + // Zero out remaining bytes if string was short + while (ii < 16) { + buf[i + ii++] = 0; + } + + return buf; + } + + // **`unparse()` - Convert UUID byte array (ala parse()) into a string** + function unparse(buf, offset) { + var i = offset || 0, bth = _byteToHex; + return bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]]; + } + + // **`v1()` - Generate time-based UUID** + // + // Inspired by https://github.com/LiosK/UUID.js + // and http://docs.python.org/library/uuid.html + + // random #'s we need to init node and clockseq + var _seedBytes = _rng(); + + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + var _nodeId = [ + _seedBytes[0] | 0x01, + _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5] + ]; + + // Per 4.2.2, randomize (14 bit) clockseq + var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff; + + // Previous uuid creation time + var _lastMSecs = 0, _lastNSecs = 0; + + // See https://github.com/broofa/node-uuid for API details + function v1(options, buf, offset) { + var i = buf && offset || 0; + var b = buf || []; + + options = options || {}; + + var clockseq = (options.clockseq != null) ? options.clockseq : _clockseq; + + // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + var msecs = (options.msecs != null) ? options.msecs : new Date().getTime(); + + // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + var nsecs = (options.nsecs != null) ? options.nsecs : _lastNSecs + 1; + + // Time since last uuid creation (in msecs) + var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; + + // Per 4.2.1.2, Bump clockseq on clock regression + if (dt < 0 && options.clockseq == null) { + clockseq = clockseq + 1 & 0x3fff; + } + + // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) { + nsecs = 0; + } + + // Per 4.2.1.2 Throw error if too many uuids are requested + if (nsecs >= 10000) { + throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + + // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + msecs += 12219292800000; + + // `time_low` + var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; + + // `time_mid` + var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; + + // `time_high_and_version` + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + b[i++] = tmh >>> 16 & 0xff; + + // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + b[i++] = clockseq >>> 8 | 0x80; + + // `clock_seq_low` + b[i++] = clockseq & 0xff; + + // `node` + var node = options.node || _nodeId; + for (var n = 0; n < 6; n++) { + b[i + n] = node[n]; + } + + return buf ? buf : unparse(b); + } + + // **`v4()` - Generate random UUID** + + // See https://github.com/broofa/node-uuid for API details + function v4(options, buf, offset) { + // Deprecated - 'format' argument, as supported in v1.2 + var i = buf && offset || 0; + + if (typeof(options) === 'string') { + buf = (options === 'binary') ? new BufferClass(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || _rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ii++) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || unparse(rnds); + } + + // Export public API + var uuid = v4; + uuid.v1 = v1; + uuid.v4 = v4; + uuid.parse = parse; + uuid.unparse = unparse; + uuid.BufferClass = BufferClass; + uuid._rng = _rng; + uuid._mathRNG = _mathRNG; + uuid._nodeRNG = _nodeRNG; + uuid._whatwgRNG = _whatwgRNG; + + if (('undefined' !== typeof module) && module.exports) { + // Publish as node.js module + module.exports = uuid; + } else if (typeof define === 'function' && define.amd) { + // Publish as AMD module + define(function() {return uuid;}); + + + } else { + // Publish as global (in browsers) + _previousRoot = _window.uuid; + + // **`noConflict()` - (browser only) to reset global 'uuid' var** + uuid.noConflict = function() { + _window.uuid = _previousRoot; + return uuid; + }; + + _window.uuid = uuid; + } +})('undefined' !== typeof window ? window : null); \ No newline at end of file