text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <title>JSDoc: Source: jsxc.lib.webrtc.js</title>

    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">

Source: jsxc.lib.webrtc.js

/* global jsxc, Strophe, SDPUtil, getUserMediaWithConstraints, setupRTC, jQuery, MediaStreamTrack */

var RTC = null, RTCPeerconnection = null;

jsxc.gui.template.incomingCall = '<h3>%%Incoming_call%%</h3>\
        <p>%%Do_you_want_to_accept_the_call_from%% {{bid_name}}?</p>\
        <p class="jsxc_right">\
            <a href="#" class="button jsxc_reject">%%Reject%%</a> <a href="#" class="button creation jsxc_accept">%%Accept%%</a>\
         </p>';

jsxc.gui.template.allowMediaAccess = '<p>%%Please_allow_access_to_microphone_and_camera%%</p>';

jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\
            <div class="jsxc_chatarea">\
                <ul></ul>\
            </div>\
            <div class="jsxc_videoContainer">\
                <video class="jsxc_localvideo" autoplay></video>\
                <video class="jsxc_remotevideo" autoplay></video>\
                <div class="jsxc_status"></div>\
               <div class="bubblingG">\
                  <span id="bubblingG_1">\
                  </span>\
                  <span id="bubblingG_2">\
                  </span>\
                  <span id="bubblingG_3">\
                  </span>\
               </div>\
                <div class="jsxc_noRemoteVideo">\
                   <div>\
                     <div></div>\
                     <p>%%No_video_signal%%</p>\
                     <div></div>\
                   </div>\
                </div>\
            </div>\
            <div class="jsxc_controlbar">\
                <button type="button" class="jsxc_hangUp">%%hang_up%%</button>\
                <input type="range" class="jsxc_volume" min="0.0" max="1.0" step="0.05" value="0.5" />\
                <div class="jsxc_buttongroup">\
                    <button type="button" class="jsxc_snapshot">%%snapshot%%</button><button type="button" class="jsxc_snapshots">▼</button>\
                </div>\
                <!-- <button type="button" class="jsxc_mute_local">%%mute_my_audio%%</button>\
                <button type="button" class="jsxc_pause_local">%%pause_my_video%%</button> --> \
                <button type="button" class="jsxc_showchat">%%chat%%</button>\
                <button type="button" class="jsxc_fullscreen">%%fullscreen%%</button>\
                <button type="button" class="jsxc_info">%%Info%%</button>\
            </div>\
            <div class="jsxc_multi">\
               <div class="jsxc_snapshotbar">\
                   <p>No pictures yet!</p>\
               </div>\n\
               <!--<div class="jsxc_chatarea">\
                   <ul></ul>\
               </div>-->\
               <div class="jsxc_infobar"></div>\
            </div>\
        </div>';

(function($) {
   "use strict";

   /**
    * WebRTC namespace for jsxc.
    *
    * @namespace jsxc.webrtc
    */
   jsxc.webrtc = {
      /** strophe connection */
      conn: null,

      /** local video stream */
      localStream: null,

      /** remote video stream */
      remoteStream: null,

      /** jid of the last caller */
      last_caller: null,

      /** should we auto accept incoming calls? */
      AUTO_ACCEPT: false,

      /** required disco features */
      reqVideoFeatures: [ 'urn:xmpp:jingle:apps:rtp:video', 'urn:xmpp:jingle:apps:rtp:audio', 'urn:xmpp:jingle:transports:ice-udp:1', 'urn:xmpp:jingle:apps:dtls:0' ],

      /** bare jid to current jid mapping */
      chatJids: {},

      /**
       * Initialize webrtc plugin.
       *
       * @private
       * @memberOf jsxc.webrtc
       */
      init: function() {
         var self = jsxc.webrtc;

         // shortcut
         self.conn = jsxc.xmpp.conn;

         if (RTC.browser === 'firefox') {
            self.conn.jingle.media_constraints.mandatory.MozDontOfferDataChannel = true;
         }

         if (!self.conn.jingle) {
            jsxc.error('No jingle plugin found!');
            return;
         }

         // jingle configuration
         self.conn.jingle.PRANSWER = false;
         self.conn.jingle.AUTOACCEPT = false;
         self.conn.jingle.ice_config = jsxc.storage.getUserItem('iceConfig');
         self.conn.jingle.MULTIPARTY = false;
         self.conn.jingle.pc_constraints = RTC.pc_constraints;

         $(document).on('message.jsxc', $.proxy(self.onMessage, self));
         $(document).on('presence.jsxc', $.proxy(self.onPresence, self));

         $(document).on('mediaready.jingle', $.proxy(self.onMediaReady, self));
         $(document).on('mediafailure.jingle', $.proxy(self.onMediaFailure, self));
         $(document).on('callincoming.jingle', $.proxy(self.onCallIncoming, self));
         $(document).on('callterminated.jingle', $.proxy(self.onCallTerminated, self));
         $(document).on('ringing.jingle', $.proxy(self.onCallRinging, self));

         $(document).on('remotestreamadded.jingle', $.proxy(self.onRemoteStreamAdded, self));
         $(document).on('remotestreamremoved.jingle', $.proxy(self.onRemoteStreamRemoved, self));
         $(document).on('iceconnectionstatechange.jingle', $.proxy(self.onIceConnectionStateChanged, self));
         $(document).on('nostuncandidates.jingle', $.proxy(self.noStunCandidates, self));

         $(document).on('error.jingle', function(ev, sid, error) {
            jsxc.error('[JINGLE]', error);
         });

         if (self.conn.disco) {
            self.conn.disco.addFeature('urn:xmpp:jingle:apps:dtls:0');
         }

         if (self.conn.caps) {
            $(document).on('caps.strophe', $.proxy(self.onCaps, self));
         }

         self.getTurnCrendentials();
      },

      /**
       * Checks if cached configuration is valid and if necessary update it.
       *
       * @memberOf jsxc.webrtc
       */
      getTurnCrendentials: function() {

         if (!jsxc.options.turnCredentialsPath) {
            jsxc.debug('No path for TURN credentials defined!');
            return;
         }

         var ttl = (jsxc.storage.getUserItem('iceValidity') || 0) - (new Date()).getTime();
         if (ttl > 0) {
            // credentials valid

            window.setTimeout(jsxc.webrtc.getTurnCrendentials, ttl + 500);
            return;
         }

         $.ajax(jsxc.options.turnCredentialsPath, {
            async: true,
            success: function(data) {
               var iceConfig = {
                  iceServers: [ {
                     url: 'turn:' + data.url,
                     credential: data.credential,
                     username: data.username
                  } ]
               };

               jsxc.webrtc.conn.jingle.ice_config = iceConfig;
               jsxc.storage.setUserItem('iceConfig', iceConfig);
               jsxc.storage.setUserItem('iceValidity', (new Date()).getTime() + 1000 * data.ttl);
            },
            dataType: 'json'
         });
      },

      /**
       * Return list of video capable resources.
       *
       * @memberOf jsxc.webrtc
       * @param jid
       * @returns {Array}
       */
      getCapableRes: function(jid) {
         var self = jsxc.webrtc;
         var bid = jsxc.jidToBid(jid);
         var res = jsxc.storage.getUserItem('res', bid) || [];

         var available = [];
         $.each(res, function(r) {
            if (self.conn.caps.hasFeatureByJid(bid + '/' + r, self.reqVideoFeatures)) {
               available.push(r);
            }
         });

         return available;
      },

      /**
       * Add "video" button to roster
       *
       * @private
       * @memberOf jsxc.webrtc
       * @param event
       * @param bid bid of roster item
       * @param data data wich belongs to bid
       * @param el the roster item
       */
      onAddRosterItem: function(event, bid, data, el) {
         var self = jsxc.webrtc;

         if (!self.conn) {
            $(document).one('connectionReady.jsxc', function() {
               self.onAddRosterItem(null, bid, data, el);
            });
            return;
         }

         var videoIcon = $('<div class="jsxc_video jsxc_disabled" title="' + $.t("Start_video_call") + '"></div>');

         videoIcon.click(function() {
            self.startCall(data.jid);
            return false;
         });

         el.find('.jsxc_options.jsxc_left').append(videoIcon);

         el.on('extra.jsxc', function() {
            self.updateIcon(bid);
         });
      },

      /**
       * Add "video" button to window menu.
       *
       * @private
       * @memberOf jsxc.webrtc
       * @param event
       * @param win jQuery window object
       */
      initWindow: function(event, win) {
         var self = jsxc.webrtc;

         jsxc.debug('webrtc.initWindow');

         if (!self.conn) {
            $(document).one('connectionReady.jsxc', function() {
               self.initWindow(null, win);
            });
            return;
         }

         var div = $('<div>').addClass('jsxc_video');
         win.find('.jsxc_transfer:eq(1)').after(div);

         self.updateIcon(jsxc.jidToBid(win.data('jid')));
      },

      /**
       * Enable or disable "video" icon and assign full jid.
       *
       * @memberOf jsxc.webrtc
       * @param bid CSS conform jid
       */
      updateIcon: function(bid) {
         jsxc.debug('Update icon', bid);

         var self = jsxc.webrtc;

         if (bid === jsxc.jidToBid(self.conn.jid)) {
            return;
         }

         var win = jsxc.gui.window.get(bid);
         var jid = win.data('jid') || jsxc.storage.getUserItem('buddy', bid).jid;

         var el = win.find('.jsxc_video').add(jsxc.gui.roster.getItem(bid).find('.jsxc_video'));

         var capableRes = self.getCapableRes(jid);
         var targetRes = Strophe.getResourceFromJid(jid);

         if (targetRes === null) {
            $.each(jsxc.storage.getUserItem('buddy', bid).res, function(index, val) {
               if (capableRes.indexOf(val) > -1) {
                  targetRes = val;
                  return false;
               }
            });
         }

         el.off('click');

         if (capableRes.indexOf(targetRes) > -1) {
            el.click(function() {
               self.startCall(jid + '/' + targetRes);
            });

            el.removeClass('jsxc_disabled');

            el.attr('title', jsxc.translate('%%Start video call%%'));
         } else {
            el.addClass('jsxc_disabled');

            el.attr('title', jsxc.translate('%%Video call not possible.%%'));
         }
      },

      /**
       * Check if full jid changed.
       *
       * @private
       * @memberOf jsxc.webrtc
       * @param e
       * @param from full jid
       */
      onMessage: function(e, from) {
         var self = jsxc.webrtc;
         var bid = jsxc.jidToBid(from);

         jsxc.debug('webrtc.onmessage', from);

         if (self.chatJids[bid] !== from) {
            self.updateIcon(bid);
            self.chatJids[bid] = from;
         }
      },

      /**
       * Update icon on presence.
       *
       * @memberOf jsxc.webrtc
       * @param ev
       * @param status
       * @private
       */
      onPresence: function(ev, jid) {
         var self = jsxc.webrtc;

         jsxc.debug('webrtc.onpresence', jid);

         self.updateIcon(jsxc.jidToBid(jid));
      },

      /**
       * Display status message to user.
       *
       * @memberOf jsxc.webrtc
       * @param txt message
       * @param d duration in ms
       */
      setStatus: function(txt, d) {
         var status = $('.jsxc_webrtc .jsxc_status');
         var duration = (typeof d === 'undefined' || d === null) ? 4000 : d;

         jsxc.debug('[Webrtc]', txt);

         if (status.html()) {
            // attach old messages
            txt = status.html() + '<br />' + txt;
         }

         status.html(txt);

         status.css({
            'margin-left': '-' + (status.width() / 2) + 'px',
            opacity: 0,
            display: 'block'
         });

         status.stop().animate({
            opacity: 1
         });

         clearTimeout(status.data('timeout'));

         if (duration === 0) {
            return;
         }

         var to = setTimeout(function() {
            status.stop().animate({
               opacity: 0
            }, function() {
               status.html('');
            });
         }, duration);

         status.data('timeout', to);
      },

      /**
       * Update "video" button if we receive cap information.
       *
       * @private
       * @memberOf jsxc.webrtc
       * @param event
       * @param jid
       */
      onCaps: function(event, jid) {
         var self = jsxc.webrtc;

         self.updateIcon(jsxc.jidToBid(jid));
      },

      /**
       * Called if video/audio is ready. Open window and display some messages.
       *
       * @private
       * @memberOf jsxc.webrtc
       * @param event
       * @param stream
       */
      onMediaReady: function(event, stream) {
         jsxc.debug('media ready');

         var self = jsxc.webrtc;

         self.localStream = stream;
         self.conn.jingle.localStream = stream;

         jsxc.gui.showVideoWindow(self.last_caller);

         var i;
         for (i = 0; i < stream.getAudioTracks().length; i++) {
            self.setStatus((stream.getAudioTracks().length > 0) ? 'Use local audio device.' : 'No local audio device.');

            jsxc.debug('using audio device "' + stream.getAudioTracks()[i].label + '"');
         }
         for (i = 0; i < stream.getVideoTracks().length; i++) {
            self.setStatus((stream.getVideoTracks().length > 0) ? 'Use local video device.' : 'No local video device.');

            jsxc.debug('using video device "' + stream.getVideoTracks()[i].label + '"');
            $('#jsxc_dialog .jsxc_localvideo').show();
         }

         $(document).one('cleanup.dialog.jsxc', $.proxy(self.hangUp, self));
         $(document).trigger('finish.mediaready.jsxc');
      },

      /**
       * Called if media failes.
       *
       * @private
       * @memberOf jsxc.webrtc
       */
      onMediaFailure: function(ev, err) {
         this.setStatus('media failure');

         jsxc.gui.window.postMessage(jsxc.jidToBid(jsxc.webrtc.last_caller), 'sys', jsxc.translate('%%Media failure%%: ') + err.name);
         jsxc.debug('media failure: ' + err.name);
      },

      /**
       * Called on incoming call.
       *
       * @private
       * @memberOf jsxc.webrtc
       * @param event
       * @param sid Session id
       */
      onCallIncoming: function(event, sid) {
         jsxc.debug('incoming call' + sid);

         var self = this;
         var sess = this.conn.jingle.sessions[sid];
         var bid = jsxc.jidToBid(sess.peerjid);

         jsxc.gui.window.postMessage(bid, 'sys', jsxc.translate('%%Incoming call.%%'));

         // display notification
         jsxc.notification.notify(jsxc.translate('%%Incoming call%%'), jsxc.translate('%%from%% ' + bid));

         // send signal to partner
         sess.sendRinging();

         jsxc.webrtc.last_caller = sess.peerjid;

         jsxc.switchEvents({
            'mediaready.jingle': function(event, stream) {
               self.setStatus('Accept call');

               sess.localStream = stream;
               sess.peerconnection.addStream(stream);

               sess.sendAnswer();
               sess.accept();
            },
            'mediafailure.jingle': function() {
               sess.sendTerminate('decline');
               sess.terminate();
            }
         });

         if (jsxc.webrtc.AUTO_ACCEPT) {
            self.reqUserMedia();
            return;
         }

         var dialog = jsxc.gui.dialog.open(jsxc.gui.template.get('incomingCall', bid), {
            noClose: true
         });

         dialog.find('.jsxc_accept').click(function() {
            $(document).trigger('accept.call.jsxc');

            self.reqUserMedia();
         });

         dialog.find('.jsxc_reject').click(function() {
            jsxc.gui.dialog.close();
            $(document).trigger('reject.call.jsxc');

            sess.sendTerminate('decline');
            sess.terminate();
         });
      },

      /**
       * Called if call is terminated.
       *
       * @private
       * @memberOf jsxc.webrtc
       * @param event
       * @param sid Session id
       * @param reason Reason for termination
       * @param [text] Optional explanation
       */
      onCallTerminated: function(event, sid, reason, text) {
         this.setStatus('call terminated ' + sid + (reason ? (': ' + reason + ' ' + text) : ''));

         var bid = jsxc.jidToBid(jsxc.webrtc.last_caller);

         if (this.localStream) {
            this.localStream.stop();
         }

         if ($('.jsxc_videoContainer').length) {
            $('.jsxc_remotevideo')[0].src = "";
            $('.jsxc_localvideo')[0].src = "";
         }

         this.conn.jingle.localStream = null;
         this.localStream = null;
         this.remoteStream = null;

         var win = $('#jsxc_dialog .jsxc_chatarea > ul > li');
         $('#jsxc_windowList > ul').prepend(win.detach());
         win.find('.slimScrollDiv').resizable('enable');

         $(document).off('cleanup.dialog.jsxc');
         $(document).off('error.jingle');
         jsxc.gui.dialog.close();

         jsxc.gui.window.postMessage(bid, 'sys', jsxc.translate('%%Call terminated%%' + (reason ? (': %%' + reason + '%%') : '') + '.'));
      },

      /**
       * Remote station is ringing.
       *
       * @private
       * @memberOf jsxc.webrtc
       */
      onCallRinging: function() {
         this.setStatus('ringing...', 0);
      },

      /**
       * Called if we receive a remote stream.
       *
       * @private
       * @memberOf jsxc.webrtc
       * @param event
       * @param data
       * @param sid Session id
       */
      onRemoteStreamAdded: function(event, data, sid) {
         this.setStatus('Remote stream for session ' + sid + ' added.');

         var stream = data.stream;
         this.remoteStream = stream;

         var sess = this.conn.jingle.sessions[sid];

         var isVideoDevice = stream.getVideoTracks().length > 0;
         var isAudioDevice = stream.getAudioTracks().length > 0;

         sess.remoteDevices = {
            video: isVideoDevice,
            audio: isAudioDevice
         };

         this.setStatus(isVideoDevice ? 'Use remote video device.' : 'No remote video device');
         this.setStatus(isAudioDevice ? 'Use remote audio device.' : 'No remote audio device');

         if ($('.jsxc_remotevideo').length) {
            RTC.attachMediaStream($('#jsxc_dialog .jsxc_remotevideo'), stream);

            $('#jsxc_dialog .jsxc_' + (isVideoDevice ? 'remotevideo' : 'noRemoteVideo')).addClass('jsxc_deviceAvailable');
         }
      },

      /**
       * Called if the remote stream was removed.
       *
       * @private
       * @meberOf jsxc.webrtc
       * @param event
       * @param data
       * @param sid Session id
       */
      onRemoteStreamRemoved: function(event, data, sid) {
         this.setStatus('Remote stream for session ' + sid + ' removed.');
      },

      /**
       * Extracts local and remote ip and display it to the user.
       *
       * @private
       * @memberOf jsxc.webrtc
       * @param event
       * @param sid session id
       * @param sess
       */
      onIceConnectionStateChanged: function(event, sid, sess) {
         var sigState = sess.peerconnection.signalingState;
         var iceCon = sess.peerconnection.iceConnectionState;

         jsxc.debug('iceGat state for ' + sid, sess.peerconnection.iceGatheringState);
         jsxc.debug('iceCon state for ' + sid, iceCon);
         jsxc.debug('sig state for ' + sid, sigState);

         if (sigState === 'stable' && (iceCon === 'connected' || iceCon === 'completed')) {

            $('#jsxc_dialog .jsxc_deviceAvailable').show();
            $('#jsxc_dialog .bubblingG').hide();

            var localSDP = sess.peerconnection.localDescription.sdp;
            var remoteSDP = sess.peerconnection.remoteDescription.sdp;

            sess.local_fp = SDPUtil.parse_fingerprint(SDPUtil.find_line(localSDP, 'a=fingerprint:')).fingerprint;
            sess.remote_fp = SDPUtil.parse_fingerprint(SDPUtil.find_line(remoteSDP, 'a=fingerprint:')).fingerprint;

            var ip_regex = "(\\d{1,3}\\.\\d{1,3}.\\d{1,3}\\.\\d{1,3}) \\d+ typ host";

            sess.remote_ip = remoteSDP.match(new RegExp(ip_regex))[1];
            sess.local_ip = localSDP.match(new RegExp(ip_regex))[1];

            var regex = new RegExp(ip_regex, 'g');
            var match;
            while ((match = regex.exec(remoteSDP)) !== null) {
               if (match[1] !== sess.remote_ip) {
                  alert('!!! WARNING !!!\n\nPossible Man-in-the-middle attack detected!\n\nYou should close the connection.');
                  return;
               }
            }

            var text = '<p>';
            text += '<b>' + jsxc.translate('%%Local IP%%: ') + '</b>' + sess.local_ip + '<br />';
            text += '<b>' + jsxc.translate('%%Remote IP%%: ') + '</b>' + sess.remote_ip + '<br />';
            text += '<b>' + jsxc.translate('%%Local Fingerprint%%: ') + '</b>' + sess.local_fp + '<br />';
            text += '<b>' + jsxc.translate('%%Remote Fingerprint%%: ') + '</b>' + sess.remote_fp;
            text += '</p>';

            $('#jsxc_dialog .jsxc_infobar').html(text);
         } else if (iceCon === 'failed') {
            jsxc.gui.window.postMessage(jsxc.jidToBid(sess.peerjid), 'sys', jsxc.translate('%%ICE connection failure%%.'));

            $(document).off('cleanup.dialog.jsxc');

            sess.sendTerminate('failed-transport');
            sess.terminate();

            $(document).trigger('callterminated.jingle');
         }
      },

      /**
       * No STUN candidates found
       *
       * @private
       * @memberOf jsxc.webrtc
       */
      noStunCandidates: function() {

      },

      /**
       * Start a call to the specified jid.
       *
       * @memberOf jsxc.webrtc
       * @param jid full jid
       * @param um requested user media
       */
      startCall: function(jid, um) {
         var self = this;

         if (Strophe.getResourceFromJid(jid) === null) {
            jsxc.debug('We need a full jid');
            return;
         }

         self.last_caller = jid;

         jsxc.switchEvents({
            'finish.mediaready.jsxc': function() {
               self.setStatus('Initiate call');

               jsxc.gui.window.postMessage(jsxc.jidToBid(jid), 'sys', jsxc.translate('%%Call started.%%'));

               $(document).one('error.jingle', function(e, sid, error) {
                  if (error.source !== 'offer') {
                     return;
                  }

                  $(document).off('cleanup.dialog.jsxc');
                  setTimeout(function() {
                     jsxc.gui.showAlert("Sorry, we couldn't establish a connection. Maybe your buddy is offline.");
                  }, 500);
               });

               self.conn.jingle.initiate(jid, self.conn.jid.toLowerCase());
            },
            'mediafailure.jingle': function() {
               jsxc.gui.dialog.close();
            }
         });

         self.reqUserMedia(um);
      },

      /**
       * Hang up the current call.
       *
       * @memberOf jsxc.webrtc
       */
      hangUp: function(reason, text) {
         $(document).off('cleanup.dialog.jsxc');

         jsxc.webrtc.conn.jingle.terminate(null, reason, text);
         $(document).trigger('callterminated.jingle');
      },

      /**
       * Request video and audio from local user.
       *
       * @memberOf jsxc.webrtc
       */
      reqUserMedia: function(um) {
         if (this.localStream) {
            $(document).trigger('mediaready.jingle', [ this.localStream ]);
            return;
         }

         um = um || [ 'video', 'audio' ];

         jsxc.gui.dialog.open(jsxc.gui.template.get('allowMediaAccess'), {
            noClose: true
         });
         this.setStatus('please allow access to microphone and camera');

         if (typeof MediaStreamTrack !== 'undefined' && typeof MediaStreamTrack.getSources !== 'undefined') {
            MediaStreamTrack.getSources(function(sourceInfo) {
               var availableDevices = sourceInfo.map(function(el) {

                  return el.kind;
               });

               um = um.filter(function(el) {
                  return availableDevices.indexOf(el) !== -1;
               });

               getUserMediaWithConstraints(um);
            });
         } else {
            getUserMediaWithConstraints(um);
         }
      },

      /**
       * Make a snapshot from a video stream and display it.
       *
       * @memberOf jsxc.webrtc
       * @param video Video stream
       */
      snapshot: function(video) {
         if (!video) {
            jsxc.debug('Missing video element');
         }

         $('.jsxc_snapshotbar p').remove();

         var canvas = $('<canvas/>').css('display', 'none').appendTo('body').attr({
            width: video.width(),
            height: video.height()
         }).get(0);
         var ctx = canvas.getContext('2d');

         ctx.drawImage(video[0], 0, 0);
         var img = $('<img/>');
         var url = null;

         try {
            url = canvas.toDataURL('image/jpeg');
         } catch (err) {
            jsxc.warn('Error', err);
            return;
         }

         img[0].src = url;
         var link = $('<a/>').attr({
            target: '_blank',
            href: url
         });
         link.append(img);
         $('.jsxc_snapshotbar').append(link);

         canvas.remove();
      }
   };

   /**
    * Display window for video call.
    *
    * @memberOf jsxc.gui
    */
   jsxc.gui.showVideoWindow = function(jid) {
      var self = jsxc.webrtc;

      $(document).one('complete.dialog.jsxc', function() {

         // mute own video element to avoid echoes
         $('#jsxc_dialog .jsxc_localvideo')[0].muted = true;
         $('#jsxc_dialog .jsxc_localvideo')[0].volume = 0;

         var rv = $('#jsxc_dialog .jsxc_remotevideo');
         var lv = $('#jsxc_dialog .jsxc_localvideo');

         lv.draggable({
            containment: "parent"
         });

         RTC.attachMediaStream(lv, self.localStream);

         var w_dialog = $('#jsxc_dialog').width();
         var w_remote = rv.width();

         // fit in video
         if (w_remote > w_dialog) {
            var scale = w_dialog / w_remote;
            var new_h = rv.height() * scale;
            var new_w = w_dialog;
            var vc = $('#jsxc_dialog .jsxc_videoContainer');

            rv.height(new_h);
            rv.width(new_w);

            vc.height(new_h);
            vc.width(new_w);

            lv.height(lv.height() * scale);
            lv.width(lv.width() * scale);
         }

         if (self.remoteStream) {
            RTC.attachMediaStream(rv, self.remoteStream);

            $('#jsxc_dialog .jsxc_' + (self.remoteStream.getVideoTracks().length > 0 ? 'remotevideo' : 'noRemoteVideo')).addClass('jsxc_deviceAvailable');
         }

         var toggleMulti = function(elem, open) {
            $('#jsxc_dialog .jsxc_multi > div').not(elem).slideUp();

            var opt = {
               complete: jsxc.gui.dialog.resize
            };

            if (open) {
               elem.slideDown(opt);
            } else {
               elem.slideToggle(opt);
            }
         };

         var win = jsxc.gui.window.open(jsxc.jidToBid(jid));

         win.find('.slimScrollDiv').resizable('disable');
         win.find('.jsxc_textarea').slimScroll({
            height: 413
         });
         win.find('.jsxc_emoticons').css('top', (413 + 6) + 'px');

         $('#jsxc_dialog .jsxc_chatarea ul').append(win.detach());

         $('#jsxc_dialog .jsxc_hangUp').click(function() {
            jsxc.webrtc.hangUp();
         });

         $('#jsxc_dialog .jsxc_snapshot').click(function() {
            jsxc.webrtc.snapshot(rv);
            toggleMulti($('#jsxc_dialog .jsxc_snapshotbar'), true);
         });

         $('#jsxc_dialog .jsxc_snapshots').click(function() {
            toggleMulti($('#jsxc_dialog .jsxc_snapshotbar'));
         });

         $('#jsxc_dialog .jsxc_showchat').click(function() {
            var chatarea = $('#jsxc_dialog .jsxc_chatarea');

            if (chatarea.is(':hidden')) {
               chatarea.show();
               $('#jsxc_dialog .jsxc_webrtc').width('900');
               jsxc.gui.dialog.resize({
                  width: '920px'
               });
            } else {
               chatarea.hide();
               $('#jsxc_dialog .jsxc_webrtc').width('650');
               jsxc.gui.dialog.resize({
                  width: '660px'
               });
            }
         });

         $('#jsxc_dialog .jsxc_info').click(function() {
            toggleMulti($('#jsxc_dialog .jsxc_infobar'));
         });

         $('#jsxc_dialog .jsxc_fullscreen').click(function() {

            if ($.support.fullscreen) {
               // Reset position of localvideo
               $(document).one('disabled.fullscreen', function() {
                  lv.removeAttr('style');
               });

               $('#jsxc_dialog .jsxc_videoContainer').fullscreen();
            }
         });

         $('#jsxc_dialog .jsxc_volume').change(function() {
            rv[0].volume = $(this).val();
         });

         $('#jsxc_dialog .jsxc_volume').dblclick(function() {
            $(this).val(0.5);
         });
      });

      jsxc.gui.dialog.open(jsxc.gui.template.get('videoWindow'), {
         noClose: true
      });
   };

   $.extend(jsxc.CONST, {
      KEYCODE_ENTER: 13,
      KEYCODE_ESC: 27
   });

   $(document).ready(function() {
      RTC = setupRTC();

      if (RTC !== null) {
         RTCPeerconnection = RTC.peerconnection;

         $(document).on('add.roster.jsxc', jsxc.webrtc.onAddRosterItem);
         $(document).on('init.window.jsxc', jsxc.webrtc.initWindow);
         $(document).on('attached.jsxc', jsxc.webrtc.init);
      }
   });
}(jQuery));

Index

Namespaces

jsxc

gui

dialog

queryActions

roster

template

window

notification

options

otr

storage

webrtc

xmpp

carbons

    Documentation generated by JSDoc 3.2.2 on Wed Feb 18 2015 21:47:27 GMT+0100 (CET)

redpajama_set_name: RedPajamaGithub


text:
Containerized shipping began in the late 1960's. Containerized shipping can reduce the movement of insects from the commodities in one shipping container to the commodities in another, but if not cleaned shipping containers can be a source of insect infestation of commodities during shipping. The shipping containers can be used as fumigation chambers. The following 58 papers are on management of stored product insect pests in shipping containers.
Anonymous 2003. Sea Container Review. Ministry of Agriculture and Forestry (MAF) , Auckland, New Zealand Discussion Paper No. 35, 116 p.
Ball, S. and van S Graver, J. E. 1997. Pressure tests to determine need for sheeting loaded freight containers before fumigation. p. 353–358. In Proceedings of the International Conference on Controlled Atmosphere and Fumigation in Stored Products, (Donahaye, E. J., Navarro, S., Varnava, A. eds.), Printco Ltd., Nicosia, Cyprus.
Banks, H. J. 1988. Disinfestation of durable foodstuffs in ISO containers using carbon dioxide. In Transport of Fresh Fruit and Vegetables (Ferrar, P. ed.), ACIAR Proceedings No. 23, ACIAR, Canberra, pp 45–54.
Banks, H. J. and Annis, P. C. 1981. Treatment of bulk grain in freight containers with CO2 while in transit as an insect control measure: a commercial trial using bulk malt. CSIRO Division of Entomology Report No. 26.
Banks, H. J. and Alister K. Sharp 1979. Trial use of CO2 to control insects in exported, containerized wheat. CSIRO Australia Division of Entomology Report No. 15.
Banks, H. Jonathan and Alister K. Sharp 1986. Influence of transportation on gas loss from freight containers under fumigation. Part II: Descriptive Model. Pestic. Sci. 17: 221-229.
Banks, H. J., A. K. Sharp and A. R. Irving 1974. Gas interchange in freight containers. p. 519–531. In In Brady, E.U.; Brower, J.H.; Hunter, P.E.; Jay, E.G.; Lum, P.T.M.; Lund, H.O.; Mullen, M.A.; Davis, R. (Eds.), Proceedings of the 1st International Working Conference on Stored-Product Entomology, 7-11 October 1974, Savannah, Georgia, USA. Savannah, Georgia, USA, 1975.
Banks, H. J., A. K. Sharp and A. R. Irving. 1986. Influence of transport on gas loss from freight containers under fumigation. Part I: Experimental Investigation. Pestic. Sci. 17: 207-220.
Catley, A. 1980. Container infestation: the realities and the remedies. Cargo systems International 7:71-73.
Childs, D. P., J. E. Overby, and D. Niffenegger. 1971. Phosphine fumigation of tobacco in freight containers (Part I & II). Tobacco Sci. 15: 1-6 , 33-38.
Childs, Dana P. 1972. Experiment: Tobacco consignment fumigated in containers while in transit. Container News 7: 26.
Cogan, P. M. 1997. The use of traps to monitor insect infestations in cocoa container shipments. p. 649. In Donahaye, E. J., Navarro, S. and Varnava, A. eds. Proceedings of the International Conference on Controlled Atmosphere and Fumigation in Stored Products, Nicosia, Cyprus, 21-26 April, 1996, Printco Ltd., Nicosia, Cyprus.
De Lima, C. P. F. 1994. Improved procedures for fumigation of oaten hay in shipping containers. In E. Higley, E. J. Wright, H. J. Banks and B. R. Champ eds. Proceedings of the 6th International Working Conference on Stored Product Protection, 17-24 April 1994, Canberra, Australia. CAB International, Wallingford, UK
Freeman, J. A. 1961. Inherent vice and infestation of cargo. Journal of the Insurance Institute of London. 50:97-108.
Freeman, J. A. 1967. Implications for infestation control of the use of freight containers in international trade. Stored Prod. Conf. EPPO Publ.Ser.A. 46E
Freeman, J. A. 1968. Problems in the carriage of infested commodities in freight containers. p. 79-81. Proc. Internat. Container Symposium London Chamber of Commerce
Freeman, J. A. 1974. A review of changes in the pattern of infestation in international trade. EPPO Bull. 4: 251-273.
Graver, J. E. van Someren and H. J. Banks. 2008. Freight Containers – Are They Sufficiently Gastight for Quarantine & Pre-shipment Fumigation with Methyl Bromide in the 21ˢᵗ Century? p. 441-445. In Guo, D. L., S. Navarro, Y. Jian, T. Cheng, J. Zuxun, L. Yue, L. Yang and W. Haipeng (eds.), Proceedings of the 8th International Conference on Controlled Atmospheres and Fumigation in Stored Products, 21-26 Sept. 2008, Chengdu, China. Sichuan Publishing House of Science and Technology, Chengdu, China.
Harris, A. H. 1984. Phosphine fumigation of tobacco in freight containers. Tropical Stored Products Information 49: 19-25.
Hicks, P A. 1980. Ventilated box: one special solution. Cargo Systems International 7(2): 34-35, 37, 39, 41
Jamieson, L. E., S. K. Wimalaratne, B. L. Bycroft, C. W. van Epenhuijsen, B. B. C. Page, K. G. Somerfield, N. E. M. Page-Weir, A. Chhagan, D. W. Brash, and F. Zulhendri. 2009. Feasibility of ozone for treating sea containers. Ministry of Agriculture and Forestry (MAF) Biosecurity New Zealand Technical Paper No: 2010/01, Wellington, 69 p.
Jay, E., R. Davis and J. M. Zehner 1983. In-transit fumigation of truck-ship containers with hydrogen phosphide. USDA, ARS, Adv. Agric. Techn. AAT-S-28.
Jonfia-Essien, W., S. Varro and P. Villers. 2010. Hermetic storage: a novel approach to the protection of cocoa beans. African Crop Science Journal 18(2): 59-68
Kitagawa, M., M. Saeki, J. Fukamachi, Y. Hikosaka, E. Aihara, K. Matuoto, K. Ohto and I. Hosokawa. 1984. Trial assembly and performance test of a vehicle-installed inspection device for cereals stored in sea containers. Shokubutsu Boekijo chosa kenkyu hokoku. Research Bulletin of the Plant Protection Service, Japan. 20: 47-53.
Low, A., Husing, U., Preisser, A. and Baur, X. 2003. Regulations and control of in-transit fumigated containers as well as of fumigated cargo ships. International Maritime Health, 54: 77–85.
Mabbett, T. 1995. Pheromone traps reduce insurance fumigation for cocoa bean pests. International Pest Control. 37: 73-74.
Masters, R. 2003. Containers under fumigation – the hidden danger. Paper Presented in the Fumigation Revolution Seminar Organized by the Pest-Ex 2003. International Pest Control 45: 269–270, 272.
Navarro, S., N. Paster and Y. Carmi. 1988. Prevention of condensation damage to groundnuts in containers using calcium chloride. Crop Protection 7(3): 198-201.
Paini, D. R., and D. Yemshanov. 2012. Modelling the arrival of invasive organisms via the international marine shipping network: a Khapra beetle study 7(9): PloS one e44589.
Prickett, A. J., 1987: Maintaining insecticide susceptibility in stored grain pests. Donahaye, E.; Navarro, S. (Eds.), Proceedings of the Fourth International Working Conference on Stored Product Protection, Tel Aviv, Israel, 21-26 September 1986: 407-417 Maor-Wallach Press, Jerusalem, Israel (Table 3. Frequency of infestation of commodities imported in freight containers)
Rajendran, Somiahnadar. Fumigation of shipping or freight containers. Outlooks on Pest Management 15, no. 5 (2004): 222-228.
Rutter, I. 1978. Pesticide residues in food arising from transport in freight containers. Chemistry and Industry 531-532. Call Number 1023
Schliesske, J. 1994. Zum Problem der Lagerhygiene als einem Aspekt des Vorratsschutzes im modemen Seehafenbetrieb. (On the problem of storage hygiene as an aspect of storage protection in modern seaport operation) p. 193. In Laux, Wolfrudolf (ed.), 49. Deutsche Pflanzenschutztagung/ German Plant Protection Conference. In Mitteilungen aus der Biologischen Bundesanstalt für Land- und Forstwirtschaft Berlin-Dahlem 301, 26-29 September 1994, Heidelberg. Blackwell Wissenschafts-Verlag, Berlin.
Schliesske, J. 1995. Zur gutachterlichen Feststellung des zeitpunkits eines Insekterbefalls an vegetabilen Importgutern aus Ubersee. (For the expert assessment of the timing of an insect infestation on vegetable imported goods from overseas) Mitteilungen der deutschen Gesellschaft für allgemeine und angewandte Entomologie 10: 255-258.
Schliesske, J. 1996. Post-harvest problems connected with the import of plant products carried in containers from overseas countries to Europe, pp. 181-184. In Anonymous Stored product protection and post-harvest treatment of plant products, proceedings international forum, 7-8 November 1995, Strasbourg, France. Council of Europe Publishing
Schliesske, Joachim 1997. Phytosanitare Aspekte bei importiertem Rohkakao (Theobroma cacao L.) im Hamburger Hafen. (Phytosanitary aspects of imported raw cocoa (Theobroma cacao L.) in the Port of Hamburg) Der praktische Schädlingsbekämpfer (The practical pest control specialists) 49(9): 7-9.
Schliesske, Joachim 1997. Zum Spektrum und zur wirtschaflichen Bedeutung der mit Rohkakao und Rohkaffee importierten Insektenfauna auf den Lägern des Hamburger Hafens. (On the spectrum and the economic significance of the insect fauna imported with raw cocoa and green coffee on the warehouses of the Port of Hamburg) Mitteilungen der Deutschen Gesellschaft für allgemeine und angewandte Entomologie 11: 227- 231.
Schliesske, J., Bartels, D. and Quelle, A. 1998. Zur Entwicklung von Vorratsschadlingen unter dem Einfluss transporttechnologischer Erschutterungen. (For the development of storage pests under the influence of transport technological shocks) Der praktische Schädlingsbekämpfer (The practical pest control specialists) 50(1): 27-28.
Schliesske, J. 1998. Zur Einschleppung von Insekten durch moderne Transportfazilitäten im Seegüterverkehr. (For the introduction of insects by modern transport facilities in freight transport). Verhandlungen der Westdeutschen Entomologentag 1997 57-65.
Schliesske, J. 1999. Phytosanitary aspects on imported raw cocoa. Hamburg harbour how to keep the cocoa supply safe. Zucker-und Suesswarenwirtschaft (Germany) 450-451.
Schliesske, J. 2000. Zur Gefahr der Einschleppung von Insekten mit importierten Vegetabilien durch den modernen Seegüterverkehr und die daraus resultierenden Konsequenzen für die Eingangskontrolle und die Lagerung im Binnenland (On the risk of insect introduction with vegetal products by modern sea transport, and the consequences for the phytosanitary inspections and the stores in the inland), pp. 296-297. In Anonymous 52. Deutsche Pflanzenschutztagung/German Plant Protection. in Mitteilungen aus der Biologischen Bundesanstalt für Land- und Forstwirtschaft Berlin-Dahlem H. 376, 9.-12. Oktober 2000, Freising-Weihenstephan.
Schliesske, Joachim 2000. Zur Arthropodenfauna und ihrer phytosanitären Konsequenzen in Importsendungen von Rohkakao (Theobroma cacao L.) aus westafrikanischen Ländern. (On arthropod fauna and its phytosanitary consequences in import shipments of raw cocoa (Theobroma cacao L.) from West African countries) Entomologica Basiliensia 22: 107-114.
Schliesske, Joachim. 2000. Zum Vorkommen mycetophager Kafer an vegetabilen Importgutern in Abhangigkeit von der Warenart iher Herkunft und der Transortweise. (On the occurrence of mycetophagus beetles on vegetable import goods depending on the type of goods of their origin and the mode of transort) Verhandlungen der Westdeutschen Entomologentag 1999, Lobbecke-Museum: 125-129.
Schliesske, Joachim 2001. Zum Wandel der Transportraum-Entomologie. (On the change of transport space entomology) Mitteilungen der Deutschen Gesellschaft für Angewandte Entomologie 13: 149-160.
Schliesske, Joachim 2004. Zum Einfluss des Seegüterumschlags auf die Artenzusammensetzung der Fauna synanthroper Käfer im Hamburger Hafen. (On the influence of maritime cargo handling on the species composition of the fauna synanthropic beetle in the Port of Hamburg) Mitteilungen der Deutschen Gesellschaft für allgemeine und angewandte Entomologie 14: 403-406.
Schliesske, Joachim. 2013. Vom Frachtsegler zum Containerriesen, vom Kornkäfer zur Insektendiversifikation. (From the Square Rigged Cargo Ship to Huge Container Vessels, from the Granary Weevil to Insect Diversification). Journal für Kulturpflanzen, 65 (5): 204–210
Schneider, B. M.; Williams, R. E.; Smith, M. S. 2001. Fumigant confinement and half-loss times in food industry structures and shipping containers. p. 471–476. In Donahaye, E. J., Navarro, S., Leesch, J. G. eds. Proceedings of International Conference on Controlled Atmosphere and Fumigation in Stored Products, Executive Printing Services, Clovis, California, USA.
Sharp, A. K., and H. J. Banks. 1979. Trial use of CO2 to control insects in exported, containerized wheat. CSIRO Food Res. Quarterly 39:10-16.
Sharp, A. K., and H. J. Banks. 1980. Disinfestation of stored durable foodstuffs in freight containers using carbon dioxide generated from dry ice., pp. 310-314. In Anonymous First Intern. Conf. on Technol. for Development, Canberra, 24-28 November.
Sharp, A. K.; Banks, H. J.; Irving, A. R. 1986. The effect of age on the gastightness of ISO freight containers. Journal of Food Process Engineering 8: 65–80.
Sharp, A. K.; Fenner, T. L.; Greve, J. E. van S. 1979. Prevention of condensation damage to cocoa beans shipped in containers. J. Stored Prod. Res. 15: 101-109.
Smith, K. G. 1974. Containerisation of cargo and its effects on the control of stored product insect pests in international trade. Tropical Stored Products Information 27:31-36.
Soderstrom, E. L., R. T. Hinsch, A. J. Bongers, D. G. Brandl and H. Hoogendorn. 1987. Detecting adult Phycitinae (Lepidoptera: Pyralidae) infestations in a raisin-marketing channel. J. Econ. Entomol. 80: 1229-1232.
Stanaway, M. A., Zalucki, M. P., Gillespie, P. S., Rodriquez, C. M., and Maynard, G. V. 2001. Pest risk assessment of insects in sea cargo containers. Aust. J. Entomol. 40:180-192.
Stokoe. G. 1974 Condensation in containers. Cargo Res 1: 21
Taylor, R. W. D. 1995. Fumigation of freight containers – a study in Jamaica. In Proceedings, Annual International Conference on Methyl Bromide Alternatives and Emissions Reductions, San Diego, CA, USA
Villers, P., S. Navarro, and T. De Bruin. 2010. New Applications of Hermetic Storage for Grain Storage and Transport, pp. 446-451. In M. O. Carvalho, P. G. Fields, C. S. Adler, F. H. Arthur, C. G. Athanassiou, J. F. Campbell, F. Fleurat-Lessard, P. W. Flinn, R. J. Hodges, A. A. Isikber, S. Navarro, R. T. Noyes, J. Riudavets, K. K. Sinha, G. R. Thorpe, B. H. Timlick, P. Trematerra and N. D. G. White (eds.), Proceedings of the 10th International Working Conference on Stored Product Protection, 27 June-2 July 2010, Estoril, Portugal. Julius Kühn-Institut, Berlin, Germany.
Weller, G. L. and van S Graver, J. E. 2002. Field trial of carbonyl sulfide fumigation of hay in 40 ft shipping containers. In Proceedings of the 2002 Annual International Research
Conference on Methyl Bromide Alternatives and Emissions Reductions, Orlando, Florida.

redpajama_set_name: RedPajamaCommonCrawl


text:
Ес-Суассі () — округ в Тунісі. Входить до складу вілаєту Махдія. Центр округу — м. Ес-Суассі. Станом на 2004 рік загальна чисельність населення становила 46276 осіб.

Примітки

Округи Тунісу

redpajama_set_name: RedPajamaWikipedia


When he was Facebook's chief information officer, Tim Campos said he spent a lot of time hearing from executives how frustrating it was to deal with their calendar. So when he left the company in late 2016, he set out to build a better calendar.
Details: Woven, as the company and product are called, helps individuals better manage their time — including work, team and personal calendars — as well as ease the process of finding times to meet up with people.
"My job at Facebook was to make people as productive as possible," Campos tells Axios. "I care a lot about time."
The interface looks like a traditional calendar, but also allows for other ways to view your day, including a map view to schedule meetings in a way that makes geographic sense.


The Threshing Floor is rounding the corner with the last few of our New Room Conference conversations. In this episode, Joshua and Chad sit down with the Rev. Dr. Timothy Tennent, president of Asbury Theological Seminary. We have a conversation about church planting, post-Christendom and the broader scope of worldwide Christianity.
Where does the church stand in relation to the world?
Post-Christendom doesn't assume having a voice.


Whether building from the ground up or retrofitting an existing structure, California wineries embrace environmentally sensitive architecture and design, as well as building strategies that make use of natural and recycled materials. The buildings also employ both long-established and modern-day practices to reduce energy consumption and their environmental footprints.
In addition to solar panels–a common sight in wine country–wineries use natural materials such as rock, rammed earth and even hay bales to create thick walls that help to retain cool air. Underground caves keep wine at an ideal temperature without air conditioning. Retractable roofs open at night for ventilation, keeping tanks and barrels cool with minimal use of air conditioning or refrigeration.
Tasting rooms, offices and other winery spaces in California routinely use stone or timber reclaimed from existing structures, adding character as well as giving these materials a second life.
Winemakers use the force of gravity to move grapes and wine through the stages of production, eliminating the need for pumps or other machinery. California wineries use this time-honored technique to save energy and handle fragile grapes in the gentlest way possible.
Water is necessary in the winemaking process from crushing to bottling, yet California wineries have found innovative ways not only to reduce water usage but also to recycle and reuse this precious natural resource.
Process water ponds are a feature of many California wineries, where water is discharged after being used for cleaning and sterilizing equipment and facilities. The water in these ponds is treated and reused. Some wineries have installed new technology such as "biodigesters" or other types of water treatment systems that safely treat discharged water for reuse.
California wineries reuse water discharged from the winery to create wetland areas that become habitat for water fowl and other wildlife. Though it requires several extra steps in terms of water purification, wineries have found that the beauty and biodiversity generated by these wetlands is well worth the effort.
California wineries actively track usage and engage employees to conserve water and regularly test equipment for water efficiency. Additionally, water is often reused for landscape irrigation, frost and fire protection, fountains and other agricultural interests.
Throughout the state, California wineries have invested in and adopted energy efficiency measures to conserve natural resources and to minimize energy costs. Alternative sources of energy, including solar and wind power, have been widely adopted by the California wine industry.
Use of insulated tanks to cool or heat wine reduces the need for heating and refrigeration, as does installing timed door openers in winery buildings to help keep cool air in and hot air out during California's warm summer days. New energy-efficient technologies in the motors, drives and pumps commonly used in wineries have also been widely adopted.
Many California wineries have implemented energy efficient lighting systems by replacing incandescent light bulbs with compact fluorescent light bulbs, installing automatic controls to turn lights on or off and installing "task" lighting which illuminates only those areas needed at the time. Building design uses natural light where possible.
Perhaps it's only natural that with so much sunshine in California, wineries here have flocked to solar power as an alternative energy source. Some wineries are able to provide 100% of their energy needs–both in the winery and vineyard–through the use of solar panels and even generate additional energy to send back to the grid.
California wineries address solid waste management through a robust recycling program, employee training and implementation program, and environmentally-friendly purchasing for supplies from glass to corks and more. The wine industry is able to excel in solid waste reduction because the majority of solid waste generated by a winery (e.g., pomace, lees, cardboard, paper, glass) can be reused or recycled.
Common practices at California wineries include: recycling paper, plastic, cardboard and glass; creating compost areas in meeting and lunch rooms; and converting grape pomace and lees (byproducts of winemaking) to compost for use in vineyards and landscaping. Natural cork (in tasting rooms, for example) is recycled, and wineries reuse oak barrels by shaving and re-toasting them or donating them to schools or community centers for various uses.
Employee training is crucial to developing a comprehensive waste reduction program in any business. Many California wineries put together "green teams" with employees from different parts of the operation to set goals, implement reduction practices and monitor improvement. Internal communication between all winery and vineyard personnel promotes awareness and participation.
California wineries work with multiple suppliers who provide everything from glass, paper, cardboard boxes, capsules and corks to vineyard supplies, office equipment, vehicles and cleaning products. Wineries set sustainability criteria for suppliers, requiring packaging supplies to incorporate recycled or post-consumer content and vendors to take back excess supplies the winery doesn't use. Many wineries use soy-based inks and unbleached, chlorine-free cardboard for shipping boxes.


This lemon cream recipe is a classic that can be used to fill pies and macarons. A parfait also makes a great lunchbox snack or dessert. Just make sure you pack it in a container with a tight-fitting lid.
Place the eggs, sugar, lemon juice and zest, and butter into a medium saucepan. Bring to a boil over medium heat, stirring constantly. Cook for another 2 minutes while still stirring, until the mixture has thickened to a pudding consistency. Remove from the heat.
Once the lemon cream has cooled, cover surface directly with plastic wrap and place in the refrigerator.
To assemble the parfaits, layer the yogurt, lemon cream and granola. Enjoy!
Love this recipe and love your photography. The picture of the empty bowl is just perfect! Like somebody enjoyed this to the last drop it's that good. Lemon flavour brings me back to my honeymoon, when my husband and I were in Rome enjoying slushy lemon granitas in front of the Trevi fountain. Sunny memories indeed! Thanks for another great post!
Thank you Micha! That somebody who ate the parfait was me, I confess, and I enjoyed it till the last creamy spoonful! Your Roman honeymoon sounds dreamy, lemon granitas are a great idea for a summer post, thank you for sharing that!!


text:
Invest in KOKORO Spirits
Promoting Sustainability and Community with Premium Spirits from Around the World
60 SECOND PITCH
kokorospirits.com
Retail Alcohol Minority Owned Sustainability Distillery
KOKORO Spirits was founded on the belief that we can expect more from the spirits industry than just another brand of alcohol. We are a socially responsible company that shares cultural and traditional experiences from around the world. We love that spirits are best enjoyed in celebration with our friends, families, and neighbors, near & far.
Howard Cao Founder & Interim CEO @ KOKORO Spirits
Early Bird Terms: $33,151 Left
of a min $250,000 goal
Invest via a
Future Equity Agreement
$3.5M$2.8Mvaluation cap
First $100K will invest in a SAFE with a $2.8M valuation cap and 20% discount.
see more terms & learn more
20.0%discount
A SAFE gives you the right to future shares in the company. If you invest, you're betting the company will be worth more than $2.8M in the future.
How to earn a return
Learn more about SAFEs
Invest $250+ for
10% discount on your first order, a set of KOKORO Playing Cards, and a chance to sample and help us decide our next release with our spirit experts.
10% discount on your first order, the full KOKORO Swag Package, early-bird access to the sale of our limited-edition Tequila Plata Limitada, and a chance to sample and help us decide our next release with our spirit experts.
A bottle of our limited-edition Tequila Plata Limitada, a 20% discount on your first order, the full KOKORO Swag Package, and a chance to sample and help us decide our next release with our spirit experts.
see $250, $1,000, & $5,000 perks see less
Must be at least {{ min_purchase | currency:'$':0 }}
QUALIFY FOR INVESTOR PERKS AT:
{{ perk.qualifying_amount | currency:"$":0 }}
Investor Perk: {{ current_perk().description | htmlAmpRemove }}
{{ distance_from_next_perk() | currency:"$":0 }} away from next level perks
{{ investment.amount | currency:"$":0 }}
Cancel Investment
Watch for Updates
Held in Escrow & Refundable.
Ask a Question 8
Why you may want to invest in us...
1 Our 1st product is an award-winning tequila with back-to-back gold medals from San Francisco World Spirits Competition.
2 Our team of seasoned advisors and industry professionals has experience guiding billion-dollar companies to exit.
3 US retail sales of spirits are up 32% in 2020 with online alcohol sales growing at almost 500% from last year.
4 Our Direct-To-Consumer model leverages the increase in consumer demand and will quickly build brand enthusiasts.
5 We are a California Benefit Corporation, a Pending B Corp, and a member of 1% for the Planet.
Why investors us
we've raised $208,199 since our founding
I like the concept (Artisanal formulations utilizing top quality components), I like the Founder/CEO, Howard Cao (he's a winner with all the drive and ingenuity needed for success), I like the market (it may seem crowded, but with proper positioning, there is a very profitable niche for Kokoro) and most importantly, it is a great product. All of the elements are there for great success. The business plan is sound and eminently executable.
Howard has a real knack for surrounding himself with good talent and has already formed a high quality advisory council to help him build the business.
This is an excellent opportunity to get in at the very beginning of what will surely be a fun and exciting venture.
Bill Mitchell Founding Partner, Sequel Capital Management, LLC
Lead Investor Investing $5,000 this round
Booze is good.
Ben WAlline
Howard Cao
Founder & Interim CEO
Howard is the Founder & CEO of Form & Fiction Ventures, a San Francisco creative venture studio that incubates and supports socially responsible start-ups with a focus on consumer brands, digital therapeutics, and cannabinoid sciences.
Greg has directed marketing and PR efforts to help elevate many beverage alcohol brands, including a little-known tequila company (at the time) called Patrón, creating and communicating the brand narrative for a now household name & valued over $5B.
H. Joseph Ehrmann
H. is the proprietor of Elixir (one of the Top 40 Whisky Bars in America), a BNIC Certified Cognac Educator, an Authentic Caribbean Rum panelist, Level 3 WSET Spirits Certificate holder, and two-time Cocktail-of-the-Year winner at SF World Spirits.
Scott Barnum
Scott is a seasoned consumer brand executive. He has held C-suite, board, and management positions at PepsiCo, Miller Brewing, Pete's Brewing, Pyramid Breweries, and Krave Jerky. His primary focus is on strategy, operations, and corporate governance.
Advisor & Lead Investor
Bill has led companies ranging in size from $50M to $20+B as President, CEO, and Chairman of the Board. He is the Founding Partner of Sequel Venture Partners and a partner at Sage Partners. He also served on the board at Brown-Forman for many years.
Ken MacKenzie
Ken has 20+ years of experience in the tequila industry as the CEO of Amate Tequila and Co-Founder & COO of Republic Tequila. He is currently the Co-Founder & CEO of Fresh Victor, an all-natural, fresh juice, craft cocktail mixer company.
Tiffany McNeil
Tiffany is the founder of Oaktown Strategy and focused on using consumer insights and human-centered design to inform strategic decisions. She works with mission-driven consumer brands such as Impossible Foods, Burton Snowboards, and Plum Organics.
Andy Roos
Andy is a partner at HBSE Ventures, a venture capital fund formed within HBSE, leveraging HBSE's global portfolio, expertise, and resources to invest in companies at the cross-section of sports, entertainment, and technology.
The KOKORO Spirits Story
It Started With A Sip
Three years ago on National Tequila Day, our founder, Howard Cao, dug around in our studio's cupboard and stumbled upon an old bottle of tequila that had been inadvertently neglected over the years. Dusting it off, he popped open the bottle, took a sip, and was absolutely moved. He thought of the people and hard work that went into making such a fine tequila, not to mention the agave and beautiful regions they were sourced from. Above all, he wondered how the spirits we drink today could bring so many people together but with so little appreciation for the spirits' culture and heritage. This insight inspired him to design something he could share with his friends and family.
What initially began as a clever holiday gift, evolved into KOKORO Spirits, a company that curates a collection of premium spirits and a brand that celebrates communities and cultures from around the world.
As a California Benefit Corporation and Pending B Corp, we are focused on the triple bottom line: profit, people, and the planet. Doing our part as an independent bottler, we are mindful of how we source and procure our spirits by partnering only with like-minded distilleries who align with our values of social and environmental responsibility. We are also a member of 1% for the Planet, a non-profit that has given more than a quarter of a billion dollars back to society in the last 20 years.
We believe in a world that not only appreciates our connected humanity but also celebrates our individualism as well. As part of that belief, we use ancestral distillation techniques to craft innovative and traditionally-untraditional spirits to share with the world.
Once we defined our purpose, we started on the design. First and foremost, the bottle. We wanted a shape that was iconic, catchy, but not indulgent and garish. And of course, Howard's Midwest upbringing probably had something to do with our bottle's similarities to a moonshine jug. For our logo, we started with a minimalist approach, placing XXX XXX as a substitute for our yet to be named brand. The six X's looked so good that we decided to keep them. We intend to use the same bottle and design across our entire collection of spirits as a symbol and reminder that it's not the vessel, but what's inside that matters most. As we took a deeper dive into what that meant, we were introduced to KOKORO.
Our brand celebrates communities and cultures from around the world, and so we chose a name that eloquently describes this sentiment. KOKORO is a Japanese expression that unites the notions of heart, mind, and spirit; which are considered indistinguishable from one another. Interestingly enough, a mindfulness practitioner recently explained that our placeholder "X's" are actually a rune for *gebō or "gift" which symbolizes the relationship between giving, receiving, and learning to give responsibly. All the pieces serendipitously fell into place as we embraced our mash-up of cultures. Not as appropriations, but as an inspiration of how disparate ideas can beautifully merge together into one, fulfilling the meaning behind KOKORO Spirits as our namesake.
Our First Stop: The Highlands of Jalisco
Given National Tequila Day was the initial spark for our KOKORO journey, the choice for our first release was obvious. Considering the hundreds of distilleries we could have partnered with, we were drawn to Destiladora Bonanza, a vibrant, family-owned distillery based in the highlands of Jalisco with a heritage of tequila making that dates back to 1886. Even more impressive is their focus on social and environmental responsibility and gender equality, echoing our mission.
Their master distiller, Rocío Rodriguez, one of only a handful of female tequila master distillers, has a passion for crafting with ancestral techniques, allowing us to develop an innovative, traditionally-untraditional tequila plata that will surprise and delight both new and experienced tequila lovers. Our relationship with Bonanza & Rocío solidified when we independently selected the same tasting notes for our final tequila. That is when we knew that we crafted a tequila that both KOKORO Spirits and Bonanza would be proud to share with the world
Quality Supported by Two Gold Medals
The first introduction of Rocio's tequila expression was presented by KOKORO Spirits at the 2019 San Francisco World Spirits Competition as Tequila Plata. Our hard work and research did not go unnoticed as we were awarded a gold medal. Merely our first milestone, we didn't stop there. With the help of our partnership with Destiladora Bonanza, we continued to immerse ourselves in all things tequila and kept exploring expressions to perfect the taste. As a result, we were awarded our second gold medal at the 2020 San Francisco World Spirits Competition.
Two gold medals, back-to-back. Wow. It was truly an honor to be recognized not only for our unique taste but also for the time and effort that we put into creating an exceptional tequila. After two successful industry awards, the time to launch our Tequila Plata was next. Moving forward, we will continue to master our proven abilities to find and curate the rest of our collection of impeccable spirits. We have already begun drawing plans and setting timelines for our next spirit and intend to launch it within a few months of shipping our tequila.
Award-Winning Tasting Notes
Our Tequila Plata starts with the traditional slow roasting of the piña - the heart of the blue agave plant. After 48 hours of roasting, the piña is crushed by a tahona to extract the aguamiel for fermentation. Our tequila provides an inviting aroma of cooked agave, ripe apple, and dusted pineapple that leads you to sweet herbal and caramel flavors. Made to be sipped, the light alcohol impact and lingering notes of floral, citrus, and light ginger allow for a smooth, harmonious experience.
Uncertain Times Call for KOKORO
We feared that the current world issues would slow down our launch, but the market is telling us otherwise. US retail sale of spirits is up 32% in 2020 and online alcohol sales are skyrocketing at almost 500% from last year. It became apparent that our eCommerce model is ideal in the current climate for delivering our spirits directly to our customers' doorsteps. Moreover, our distributors, American Spirits Exchange, and online fulfillment partner, Speakeasy Company, are the reliable anchors in supporting our online sales and distribution needs. There's no better time to launch KOKORO Spirits than now.
As we shake up the traditional three-tiered system of selling alcohol, our direct-to-consumer model will allow us not only to maximize gross margins but will create a unique, firsthand experience that can quickly build a community of KOKORO enthusiasts and advocates.
Why Crowdfunding?
Investing in KOKORO Spirits will not only give our investors the chance to be a part of curating a collection of exceptional spirits, but it is also a gateway for anyone to invest in. You shouldn't have to be a millionaire or a celebrity's best friend to have the opportunity to invest in a new company that you truly believe in. That's why we're setting our minimum investment at only $100. We've already had a fair amount of large, private funding offers, but as a company that focuses on the celebration of community and camaraderie, keeping the opportunity of KOKORO Spirits within a small, exclusive network just doesn't fit our core beliefs and values. While we certainly won't turn down any large crowdfunding investments, our main goal is to democratize and diversify our shareholders and to provide all investors an opportunity to join our community and cause.
Expanding Our Journey with You
Entering the tequila market provides us with a pretty safe bet. US tequila sales have been prosperous - reaching almost $9.3B in 2018 and continuing to grow. Even capturing a small fraction of that could grow our company beyond the point of financial sustainability.
While our award-winning tequila leads by example, we can promise that our next spirit categories will be just as exceptional in both the quality and our sourcing methodology, staying true to our core beliefs and values. Reaching these distinguishable heights will require meticulous planning and dedication; something KOKORO Spirits thrives on. In turn, investors will get to be a part of this culture by having the opportunity to communicate with us directly and provide their input. Our current priority may be getting our award-winning tequila to the doorsteps of our customers, but our long term goal is to expand our collection of spirits and experiences that will speak to enthusiasts across the world. We can't wait for you to join us on the adventure of selecting our next spirit. Be it Scotland, the Caribbean, Southeast Asia, the Netherlands, or even our home country, The United States, our opportunities to explore and share the world's spirits are boundless.
Where Your Money Will Go
With your investment, KOKORO Spirits will be able to officially take flight. We have built a plan to get to market as efficiently as possible, by leveraging our creative partners and advisors. Our largest use of capital will go to fulfill the initial run of our first product line - tequila. A significant portion of the funding will be utilized to support hyper-targeted marketing activities (e.g., social media and email marketing) to raise brand awareness and generate customer trials, and includes the procurement of our one-of-a-kind collection of swag for consumers. The remaining share will go towards operating costs and working capital.
We hope you share the same enthusiasm for premium spirits and our desire to celebrate cultures and communities from across the globe. Let's start this journey together and
xxx EXPLORE THE WORLD WITH US, ONE SPIRIT AT A TIME xxx
KOKORO Spirits
Read More of the story
Investor Q&A
What does your company do?
We source, curate, and promote premium spirits from around the world not only to honor a region's traditional distillation methods but also to celebrate and share their culture and communities.
Where will your company be in 5 years?
We intend to be the premier destination for spirits enthusiasts who are looking for highly curated and multicultural experiences. We see ourselves transcending from a premium independent bottler to an international lifestyle brand, all while doing our part in preserving the legacy and richness of different cultures from across the world.
Why did you choose this idea?
How far along are you? What's your biggest obstacle?
We have secured a production contract with a family-owned tequila distillery that traces its roots back to 1886. We are ready to start producing our award-winning tequila on a large scale and have our distributor (American Spirits Exchange) and our online fulfillment partner (Speakeasy Company) ready to support our direct-to-consumer sales. Unfortunately, due to COVID-19, we're at 90+ days before we'll have the product in hand to ship to our customers. Fortunately, we're already in the process of curating our next spirit, which should launch much quicker than our first. Our biggest obstacle is getting brand awareness, which is why we've teamed up with a board of advisors who have decades of experience launching, marketing, and growing alcohol brands. And as a brand rooted in community, we're relying on you to spread the word on our unique brand offering, too.
Who competes with you? What do you understand that they don't?
Right now, it'll just be tequila but we eventually intend not only to compete in all the major spirits categories but to introduce lesser-known spirits to the US market as well. Our core audience is spirits enthusiasts that value multi-cultural experiences in a sustainable and thoughtful way.
How will you make money?
The majority of our revenue will come from the direct-to-consumer sales of our spirits. We'll see additional revenue streams as we expand from tequila to other spirits: rum, whiskey, scotch, gin, etc. We'll also be selling high-margin, artfully designed merchandise to promote our brand and to provide another source of revenue. As we grow and expand, we'll explore wholesale and retail channels when the economics make sense.
What are the biggest risks? If you fail, what would be the reason? What has to go right for you to succeed?
The alcohol industry is heavily saturated. Although we're launching our brand with an award-winning tequila, we don't have the celebrity endorsements or marketing resources to help really separate us from the fray. There are many other reasons we could fail. The spirits industry is a minefield of legal, production, and operational issues. Fortunately, not many of these issues are completely out of our control and can be mitigated with the right resources and experience. In order for us to succeed, we will need to convince our audience that we can provide more than just a great tequila. Our subsequent spirit selections will also need to be just as good if not better. We've got an interesting looking bottle and a decent price point to attract first time customers, but it's going to take a great tasting experience to win them over time and time again.
Why are you raising funds using crowdfunding instead of traditional methods for a pre-seed company?
Although we've already had numerous private funding offers, we felt that the democratization and diversification of investors from crowdfunding best suits our company's core beliefs and values.
Why are you only selling direct to consumers?
Direct-to-consumer sales have skyrocketed due to COVID-19. This sales model will allow us to maximize our gross margins and minimize distribution issues. It will provide us an opportunity to quickly test the market in a capital efficient and agile way. It also allows us to communicate with our customers firsthand and to respond swiftly to their needs and concerns.
KOKORO Spirits has financial statements ending December 31 2019. Our cash in hand is $0, as of July 2020. Over the three months prior, revenues averaged $0/month, cost of goods sold has averaged $0/month, and operational expenses have averaged $0/month.
January 1 to December 31
-$68,121
Short Term Debt
Raised in 2019
Cash on Hand
Management's Discussion and Analysis of Financial Condition and Results of Operations
You should read the following discussion and analysis of our financial condition and results of operations together with our financial statements and the related notes and other financial information included elsewhere in this offering. Some of the information contained in this discussion and analysis, including information regarding the strategy and plans for our business, includes forward-looking statements that involve risks and uncertainties. You should review the "Risk Factors" section for a discussion of important factors that could cause actual results to differ materially from the results described in or implied by the forward-looking statements contained in the following discussion and analysis.
We curate premium spirits from around the world not only to honor a region's traditional distillation methods but also to celebrate and share their culture and communities.
Given the Company's limited operating history, the Company cannot reliably estimate how much revenue it will receive in the future, if any.
KOKORO Spirits, Inc. was organized as a single member LLC in the State of California in June 2018. In June 2020, the Company converted to a California C Corporation.
Since then, we have:
An award-winning tequila with back-to-back gold medals from the San Francisco World Spirits Competition. (2019-2020)
US retail sales of tequila were $9.3B in 2018, with a huge demand for direct to consumer in 2020.
An experienced team of industry advisors and consultants.
California Benefit Corporation and pending B-Corp.
Historical Results of Operations
Our company was organized in June 2018 and has limited operations upon which prospective investors may base an evaluation of its performance.
Revenues & Gross Margin. For the period ended December 31, 2019, the Company had revenues of $0 compared to the year ended December 31, 2018, when the Company had revenues of $0.
Assets. As of December 31, 2019, the Company had total assets of $0, including $0 in cash. As of December 31, 2018, the Company had $0 in total assets, including $0 in cash.
Net Loss. The Company has had net losses of $68,121 and net losses of $8,638 for the fiscal years ended December 31, 2019 and December 31, 2018, respectively.
Liabilities. The Company's liabilities totaled $76,759 for the fiscal year ended December 31, 2019 and $8,638 for the fiscal year ended December 31, 2018.
Liquidity & Capital Resources
After the conclusion of this Offering, should we hit our minimum funding target, we plan on raising capital again in approximately 12 months.
We plan to use the proceeds as set forth in this Form C under "Use of Funds". We don't have any other sources of capital in the immediate future.
We will likely require additional financing in excess of the proceeds from the Offering in order to perform operations over the lifetime of the Company. We plan to raise capital in 12 months. Except as otherwise described in this Form C, we do not have additional sources of capital other than the proceeds from the offering. Because of the complexities and uncertainties in establishing a new business strategy, it is not possible to adequately project whether the proceeds of this offering will be sufficient to enable us to implement our strategy. This complexity and uncertainty will be increased if less than the maximum amount of securities offered in this offering is sold. The Company intends to raise additional capital in the future from investors. Although capital may be available for early-stage companies, there is no guarantee that the Company will receive any investments from investors.
Runway & Short/Mid Term Expenses
To date, the company has been financed with $141,350.93 in equity.
KOKORO Spirits, Inc. cash in hand is $0, as of July 2020. Over the last three months, revenues have averaged $0/month, cost of goods sold has averaged $0/month, and operational expenses have averaged $0/month, for an average burn rate of $0 per month. Our intent is to be profitable in 6 months (this is cannot be guaranteed).
One of the most significant changes is our change from LLC to a C-Corp.
Until recently, KOKORO had been incubated within Form & Fiction, a creative & venture studio. F&F has paid all of KOKORO's expenses up till now in exchange for equity.
As of this fundraising KOKORO is now an independent company with its own expenses. Monthly costs for American Spirits Exchange (importer) and Speakeasy (ecommerce distribution) as well as all production, marketing, fulfillment and other operating expenses will be incurred by KOKORO directly as of August.
In the next 3-6 months, KOKORO will begin selling its first product to customers (premium Tequila). We estimate an initial sharp increase in sales driven by launch marketing. After this initial wave, we expect stable but growing sales going forward. With success in the initial 6 months, KOKORO will start planning for the launch of our second product line. In six months we hope (but not guarantee) to generate $150,000 in revenue, $113,000 in cost of goods old, and $83,000 in operating expenses. We aim to start generate revenues as soon as we receive funds from this offering.
We expect a similar trend for expenses. We will need to spend on an initial production run, and then continue building inventory to keep up with demand. Launch costs (legal, accounting) and marketing expenses will also have an initial peak in the first 3 months post-launch. After that, we will increase spend on marketing once the data shows that incremental spend drives customer demand. With success, we will bring in additional full-time employees and develop our second product line.
Other sources of capital will include our partnership with Form & Fiction. They will continue to collaborate and engage with the brand, and contribute marketing, advertising, and operational support. The founders have a large network of interested investors that we will tap once KOKORO shows momentum.
A note from Wefunder. Unlike companies on the NASDAQ, early-stage startups have little operating history. Financial analysis is not as useful when there is limited data. It's more important to predict the size of the future market. If the founder achieves their vision, will enough customers pay the company enough money?
It's also common for fast-growing startups to lose money even faster: they are investing in future growth. In these cases, it's often better to check if the Cost of User Acquisition (CAC) is lower than the Lifetime Value (LTV) of that customer. If one spends $1000 today to make $10,000 over the next five years, that may be a smart bet. Amazon is a famous example of re-investing potential profits to maximize growth over 20 years.
Net Margin:
Gross Margin:
Return on Assets:
Revenue per Employee:
Cash to Assets:
Revenue to Receivables:
Debt Ratio:
KOKORO Spirits financials and review report 12.31 2018 2019.pdf
We have a limited operating history.
The Tequila Plata launch will be our first line and there can be no assurance that we will be able to undertake our business plan for the long term, or that we would become consistently profitable, or that our results so far are indicative of the results that we may be able to achieve in the future.
We have preferred suppliers and any interruption in their operations could impact our operations.
We have relationships with suppliers for our all aspects of our spirits, bottles, packaging, and additional products. While we would be able to find alternative suppliers if required, any disruption in the operations of our current suppliers could negatively impact our operations.
Our future success depends on the efforts of a small management team. The loss of services of the members of the management team may have an adverse effect on the company. There can be no assurance that we will be successful in attracting and retaining other personnel we require to successfully grow our business.
We could experience licensing, legal, or regulatory problems. We are subject to federal regulation of our products.
In the U.S., there is an extensive body of law and regulation covering alcoholic beverages. Among other things, these regulations control the alcohol content of our spirits and the labels we use on our packaging. Should any of these provisions be violated, we could incur fines or other penalties that would negatively impact our financial results. Additionally, in the event of government shutdowns, we may not receive timely approval for packaging labels, potentially delaying the release of new and seasonal products.
The amount of capital we are attempting to raise in this offering under Regulation Crowdfunding may not be enough to sustain our business plan, and we intend to raise additional capital in the future. As we intend to undertake additional equity or debt financing in the future, that may dilute your investment in this offering. You will not have a significant influence on the management of the company.
We may not be able to maintain and enhance our product image. We need to increase brand awareness.
The image and reputation of our products may be impacted for various reasons including litigation, complaints from regulatory bodies, or consumers resulting from quality failure, illness, or other health concerns. Such concerns, even when unsubstantiated, could be harmful to our image and the reputation of our products.
The Company may never receive a future equity financing or elect to convert the Securities upon such future financing. In addition, the Company may never undergo a liquidity event such as a sale of the Company or an IPO. If neither the conversion of the Securities nor a liquidity event occurs, the Purchasers could be left holding the Securities in perpetuity. The Securities have numerous transfer restrictions and will likely be highly illiquid, with no secondary market on which to sell them. The Securities are not equity interests, have no ownership rights, have no rights to the Company's assets or profits and have no voting rights or ability to direct the Company or its actions.
Our management has broad discretion in regards to the use of proceeds in this offering.
Our management is entrusted to make decisions in the best interest of the company. That includes using their discretion when applying the proceeds of this offering to our operations. While we state what our intended uses might be, changed circumstances and the emergence of opportunities may result in uses of proceeds that differ from what is disclosed here.
COVID-19 can materially impact our business.
It is unclear how long the COVID-19 pandemic will last and to what degree it could hurt our ability to generate revenues. For example, it could complicate our ability to procure materials and partnerships needed for production, or impact our ability to distribute to customers. There may be other effects stemming from this pandemic that are deleterious to our company which we have not yet considered.
Read More Risks
Scott Barnum Executive Chairman @ Fresh Victor 2020
Angie Cao Co-Founder @ Form & Fiction 2020
Howard Cao Co-Founder @ Form & Fiction 2018
Howard Cao Secretary CEO CFO President 2018
Securities Held
Howard Cao 670,000 Common Stock 85.9%
Past Equity Fundraises
$63,249 SAFE
07/2020 $141,350 Priced Round
Outstanding Debts
Name Form & Fiction
Amount Invested $141,350
Transaction type Priced Round
Issued 07/30/2020
Relationship Common management
Use of Funds
$250,000 67% to fund the initial order of product from our distiller, 14% for marketing, 7.5% for Wefunder expenses, 4% for operating expenses. 7.5% for working capital. Capital light model as operating and marketing support will be provided by shareholders and advisors
$350,000 48% to fund the initial order of product from our distiller, 20% for marketing, 7.5% for Wefunder expenses, 2% for operating expenses. 22.5% working capital. Capital light model as operating and marketing support will be provided by shareholders and advisors
Class of Security
(or Amount)
Common Stock 1,000,000 780,000 Yes
The Funding Portal
KOKORO Spirits is conducting a Regulation Crowdfunding offering via Wefunder Portal LLC. CRD Number: #283503.
Form C Filing on EDGAR
The Securities and Exchange Commission hosts the official Form C on their EDGAR web site.
Your commitment was sent
wefunder.com/kokorospirits is managed by Wefunder Portal LLC. Wefunder Inc. runs wefunder.com and is the parent company of Wefunder Advisors LLC and Wefunder Portal LLC. Wefunder Advisors is an exempt reporting adviser that advises SPVs used in Reg D offerings. Wefunder Portal is a funding portal (CRD #283503) that operates sections of wefunder.com where some Regulation Crowdfunding offerings are made. Wefunder, Inc. operates sections of wefunder.com where some Regulation D and A offerings are made. Wefunder, Inc. is not regulated as either a broker-dealer or funding portal and is not a member of FINRA. By using wefunder.com, you accept our Terms & Privacy Policy. If investing, you accept our Investor Agreement. You may also view our Privacy Notice.


The Hammers will be hosting the Spurs for this much-awaited clash. We witnessed West Ham manage to redeem themselves before the international break in a 3 match unbeaten run. However, they were beaten by Brighton 1-0 before heading into the break.
They will be at home against a stronger side and will surely have to do all it takes to get something from this game. Pellegrini's men have been struggling to get goals and have only netted 8 goals in the 8 played games. They have failed to score in their last three or their last 5 games.
According to me, this home game is a great chance for the Hammers to redeem themselves and prove that they are willing to mend their weaknesses and move up the table.
Tottenham is enjoying three consecutive wins which they obtained before heading into the international break. They are closely gaining into the top of the standings and are currently closing the top 5 list at position 5 with 18 points. This is just one spot below the Gunners with a 1 goal difference.
Evidently, Harry Kane looked a little worn-out before the international break. However, he must be rejuvenated after the break and will be on duty in this away matchup.
These two sides met in January this year and only settled for a 1-1 draw.
The last three meetings have seen both teams score against each other.
In the last 5 h2h meetings, both teams have equally measured up to the tasks by winning twice.
Only one draw has been recorded in the last 5 meetings.
West Ham will look forward to impressing their home fans in this matchup. Nevertheless, they are in it against a more focused and brutal force which may not give them a chance to shine at home. Perhaps, they can step up to match the strength of their opponents with at least a goal. An outright win for them may be a miracle.
They will definitely be coming into this game to win. From the look of things, the Spurs are determined and are aiming to finish inside the top four once more this season. This game will not be an easy one for them but high chances are that they will scoop the 3 points here.
Harry Kane to score at any time @ 9/10 (1.90).


text:
Carpet Washers - Symbolic Carpet Washing Rituals in Mashhad-e Ardehal
Home » Archives » Vol. 15, No. 30, 2012 » Carpet Washers - Symbolic Carpet Washing Rituals in Mashhad-e Ardehal
Author(s): Ismail Amin Moghadam
Page No: 8
Document: Carpet Washers - Symbolic Carpet Washing Rituals in Mashhad-e Ardehal - [313.25 KB] - Login / Register to download our articles.
Ardehal or Mashhad-e Ardehal is a village in Naragh town, a town which is part of Delijan city. Deligan City is one of the cities of MarkaziProvince, a province in Iran. Mashhad-e Ardahal is located west north of Ghamsar town, 49 Km west of Kashan city, 42 Km south of Qom city, and it is on the Delijan to Kashan Road. This village is located in a valley and plain which is stretched from the west north to the west south. It is 16 Km in length and 3 to 4 Km in width, and it is irrigated through a stream falling down the valley and plain and through some series of Kanats and scattered natural springs .Since this village is with mountain climate, its winter is very cold and its summer is quite mild and cooler. Therefore, Mashhad-e Ardahal is a summer resort for the people of Kashan city, especially people of Fin, a village in Kashan city.
Mashhad-e Carpet
Since Imam Soltan Ali (AS), a descendent of Imam Muhammad Bagir (AS), was martyred in Ardehal, this village is called Mashhad-e sultan Ali or Mashhad-e Ardehal. Furthermore, because of the ritual of carpet washing symbolizing a funeral for Soltan Ali (AS) held in Ardehal, this city is also called Mashhad-e carpet or Mashhad-e Carpet washers.
Oral Narrative
At that time, Arehal was ruled by 'Hareth' bearing the title 'Golden shoes of Bari Karasf'; he lived in a fortress located in Ardehal's Mountain. Through using deceptive behaviors and friendliness, this ruler, Golden Shoes, invited Soltan Ali (AS) to Bari Karasf, one of the oldest villages of the region which is now a village of Niasar town in Kashan city; Mashhad-e Ardehal, a village where the shrine of Soltan Ali (AS) is located, is approximately 1 Km of Bari Karasf village. Soltan Ali (AS) accepted Hareth's invitation and with a group of his followers he headed for Bari Karasf. This descendent of Imam Muhammad Bagher (AS) and his followers raised their tents out of the village near a hill where now the shrine of Soltan Ali (As) is located. After a few days the servant and cook of Soltan Ali found that Soltan Ali's and his follower's place of residence was surround by a group of armed forces. This cook discovered the evil intention of Hareth: he was going to kill Soltan Ali and his followers. Therefore, this cook made his wife to go to the village secretly and to inform people of the village of the evil intention of Golden shoes, i.e. Hareth.
According to an account, a war occurred between Hareth's forces and Soltan Ali's followers in an area called Darband-e Aznave, and it lasted 10 days .In this war, Soltan Ali (As) and his followers were martyred. Two days later, people of Fin became aware of this news that Soltan Ali (As) and his followers were martyred, and they headed for the plain of Ardehal on foot and on horseback; they also had spades, canes, and clubs with them .Arriving there, they were faced with the cut bodies of Soltan Ali (AS) and his followers. Soltan Ali's (As) ablution was performed by people of Fin on the third day following his martyrdom and based on his will he was buried on top of a hill near the place of his martyrdom.
There are two widespread accounts among the people concerning how his ablution was performed and how he was buried. According to one account ,people of Fin put the body of Imam Bagher's descendent on a carpet and carried it to a stream , which is today known as 'Shazde Hussein Stream', and performed his ablution. Then, they accompanied Soltan Ali's Body to the top of the present hill and gave the body to the people from Khaveh to bury it.
According to another account, since Soltan Ali(AS) was beheaded ,and since his body was cut and was covered with blood , without performing his ablution his body was put on the carpet and was carried to the top of the hill and was then buried. Following his burial, the blood-covered carpet was washed by the water of the stream, which is today known as 'Shazde Hussein Stream'.
Following this event, people of Fin made a solemn promise to go to Mashhad-e Ardehal every year; in other words, they promised to go to Mahhad-e Ardehal 13 days following the beginning of autumn In Iran or on the second Friday of autumn in Iran, which coincides with Soltan Ali's burial ceremony, so they would visit the shrine of Soltan Ali (AS) and remember his martyrdom and burial ceremony through holding the carpet washing ritual in the anniversary of his martyrdom.
To read the full article download the PDF file.


Speaking to iFollow BWFC following the full time whistle, Wanderers assistant manager Steve Parkin gave his reaction to the Whites 2-0 defeat away at Sheffield United in the Sky Bet Championship.
Wanderers assistant manager Steve Parkin spoke to bwfc.co.uk ahead of Saturday's home fixture against Swansea City in the Sky Bet Championship.
Wanderers assistant manager Steve Parkin spoke to bwfc.co.uk ahead of Wednesday's Sky Bet Championship home fixture against Nottingham Forest.
Wanderers assistant manager Steve Parkin spoke to bwfc.co.uk following on from today's victory against Derby County.
Bolton Wanderers assistant manager Steve Parkin spoke to bwfc.co.uk ahead of this weekend's Sky Bet Championship clash against Derby County.
Watch Steve Parkin's Queens Park Rangers pre-match interview with iFollow BWFC as the Wanderers assistant manager previews Saturday's trip to Loftus Road.
Assistant Manager Steve Parkin spoke to iFollow BWFC to preview this weekend's clash with Fulham.


See this guy and his well-waxed mustache? This is Napoleon III, emperor of the French Second Empire and I devoted a couple of years of my life to learning all about him, his era and a wild-haired architect whose life had a rags-to-riches narrative arc. You may find that wildly impractical, but to me, it made and continues to make good sense. Having spent so much time reading about this particular Napoleon, I was pleasantly surprised to see that he got a shout-out in "Mad Men" two weeks ago, when the creative team was brainstorming ideas for a new margarine account. I am probably one of the few people on the planet to realize that the shout-out was not quite right. In the show, Peggy said that margarine was invented by Napoleon III, who wanted to create a butter substitute for his army that wouldn't spoil. What actually happened is that the price of butter skyrocketed and in 1869 Napoleon III offered a prize to anyone who could create a more affordable butter substitute. A chemist by the name of Hippolyte Mege-Mouries created a process for churning beef tallow with milk to create what became known as oleomargarine. Although Mege-Mouries won the emperor's prize, the French never took to the product and so in 1871, the inventor worked with a Dutch firm that bolstered the product's appeal by dyeing it yellow. The rest, as they say, is history.
But I still prefer butter.
I moved across town recently and am slowly (but gratefully) digging out and trying to get a reliable wifi signal. I christened the new kitchen the other night by cooking a tasty, improvised (and fairly easy) tilapia dish. I don't have pictures, but I can give you a rough idea of the recipe and promise you that it is good. Preheat your oven to 350 degrees. Coat a baking dish with olive oil and put four tilapia pieces in it. Season both sides with salt, freshly ground black pepper and parsley. Then, squirt the juice of one lemon over the fish and then pepper it with capers. Bake for 15 minutes and serve with a green salad. Next recipe I post will have pictures and specific steps and all the other things that make blog posts worth a damn. For now, just take my word on this, try it, and let me know what you think.
* Amy Haimerl's The Detroit House: Amy is a business journalist. Her husband is a jazz pianist. They bought a big old house with a great history and are trying to renovate it without killing each other. She's writing about the experience with great humor and transparency, all against the backdrop of a city that is undergoing a renovation of its own. Great story here. You should check it out.
* Katherine McCoy's Paleo Living in the Crescent City: Katherine is a marketing professional in New Orleans and a former swimmer for Tulane. Part of the fun of her blog is watching how she tries to pursue this healthy, paleo lifestyle in a city where indulgence is always just around the corner. Her discipline is amazing and her dog Pearl is super-cute.