modules.define('bemdom', ['i-bem__dom'], function(provide, BEMDOM) {
    provide(BEMDOM);
});

modules.define('angular-bem',
    ['BEMHTML', 'bemdom', 'jquery', 'i-bem__dom_init'],
    function(provide, BEMHTML, BEMDOM, $) {

        angular.module('angular-bem', [])
            .value('bemhtml', BEMHTML)
            .value('bemdom', BEMDOM)
            .factory('ngbem', ngBemFactory)
            .directive('ngBem', ngBemDirective)
            .directive('bem', iBemDirective)
            .directive('bemMod', bemModDirective)
            .directive('bemEvent', bemEventDirective)
            .directive('menuItem', menuItemDirective);


        function ngBemFactory($compile) {
            var service = { render : render };

            return service;

            function render(bemjson, element, scope) {
                element.replaceWith(
                    $compile(BEMHTML.apply(bemjson))(scope)
                );
            }
        }

        function ngBemDirective(ngbem) {
            return {
                restrict : 'E',
                link : function(scope, element, attrs) {
                    var bemjson = scope.$eval(attrs.bemJson || element.text());

                    ngbem.render(bemjson, element, scope);
                }
            };
        }

        function bemController($scope, $attrs, $element) {
            this.bem = $scope.$eval($attrs.bem);

            angular.forEach(this.bem, function(v, k) {
                this.bem[k] = function(){
                  return $($element).bem(k);
                };
            }, this);
        }

        function iBemDirective() {
            return {
                restrict : 'A',
                require : ['bem', '?ngModel'],
                controller : bemController,
                link : function(scope, element, attrs, ctrls) {
                  scope.$evalAsync(function(){
                    var iBem = ctrls[0],
                        ngModel = ctrls[1];

                    if(!ngModel) return;

                    angular.forEach(iBem.bem, function(v, k) {
                        // iBem.bem[k] = $(element).bem(k);
                        iBem.bem[k]().on('change', function(e, data) {
                            if(data && data.source === 'ng-model') {
                                scope.$evalAsync(setModelValue.bind(iBem.bem[k]()));
                            } else {
                                scope.$evalAsync(setViewValue.bind(iBem.bem[k]()));
                            }
                        });

                        setModelValue.bind(iBem.bem[k]())();
                    });

                    ngModel.$render = function() {
                        var value = angular.isUndefined(ngModel.$viewValue)? '' : ngModel.$viewValue;
                        angular.forEach(iBem.bem, function(v, k) {
                            if(iBem.bem[k]().setVal) iBem.bem[k]().setVal(value, { source : 'ng-model' });
                        });
                    };

                    function setViewValue() {
                        ngModel.$setViewValue(this.getVal());
                    }

                    function setModelValue() {
                        // prevents calling of ng-change listeners
                        ngModel.$modelValue = this.getVal();
                    }

                  })
                }
            };
        }

        function bemModDirective() {
            return {
                restrict : 'A',
                require : 'bem',
                link : function(scope, element, attrs, iBem) {
                    var oldVal;

                    scope.$watch(attrs.bemMod, bemModWatchAction, true);

                    function setMods(newVal) {
                        angular.forEach(newVal, function(v, block) {
                            angular.forEach(v, function(modVal, modName) {
                                this.setMod(modName, modVal);
                            }, iBem.bem[block]);
                        });
                    }

                    function bemModWatchAction(newVal) {
                        if(!angular.equals(newVal, oldVal)) {
                            setMods(newVal);
                        }

                        oldVal = shallowCopy(newVal);
                    }
                }
            };
        }

        function bemEventDirective($parse) {
            return {
                restrict : 'A',
                require : 'bem',
                link : function(scope, element, attrs, iBem) {
                    var events = scope.$eval(attrs.bemEvent);

                    angular.forEach(events, function(eventsArray, block) {
                        angular.forEach(eventsArray, function(eventDefenition) {
                            var event,
                                fn;

                            if(eventDefenition.length === 2) {
                                event = eventDefenition[0];
                                fn = $parse(eventDefenition[1], null, true);
                            } else if(eventDefenition.length === 3) {
                                event = {
                                    modName : eventDefenition[0],
                                    modVal : eventDefenition[1]
                                };
                                fn = $parse(eventDefenition[2], null, true);
                            }

                            this.on(event, function() {
                                scope.$apply(function() {
                                    fn(scope);
                                });
                            });
                        }, iBem.bem[block]);
                    });
                }
            };
        }

        function menuItemDirective() {
            return {
                restrict: 'C',
                require : 'bem',
                link : function(scope, element, attrs, iBem) {
                  scope.$evalAsync(function(){
                      var menu = iBem.bem['menu-item']().findBlockOutside('menu');
                      menu._hoveredItem = null;
                      menu._items = null;
                      menu.getItems().delMod('checked');
                      menu.setVal(menu.getVal() || menu.getItems()[0].getVal());
                  });
                }
            };
        }

        function shallowCopy(src, dst) {
            if(angular.isArray(src)) {
                dst = dst || [];

                for(var i = 0, ii = src.length; i < ii; i++) {
                    dst[i] = src[i];
                }
            } else if(angular.isObject(src)) {
                dst = dst || {};

                for(var key in src) {
                    if(!(key.charAt(0) === '$' && key.charAt(1) === '$')) {
                        dst[key] = src[key];
                    }
                }
            }

            return dst || src;
        }

        provide(angular.module('angular-bem'));
    }
);

modules.require(['angular-bem', 'jquery', 'identify'], function(ng, j, id){
    window.$ = j;
    angular.module('app', ['angular-bem'])
        .controller('appController', function AppController(){
            var vm = this;

            vm.hello = 'Hello, World';

            vm.select = [2];
            
            vm.id = id;
            
            vm.llog = [];
            
            vm.items = ['qew','ads','czx','sdf','wtr2qwy'];

            vm.log = function(l){
                console.log(l);
                vm.llog.push(l);
            };
        });

    angular.bootstrap(document, ['app']);
});
<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <link data-require="bem-components@2.2.0" data-semver="2.3.0" rel="stylesheet" href="https://yastatic.net/bem-components/2.3.0/desktop/bem-components.css" />
    <script data-require="bem-components@2.2.0" data-semver="2.3.0" src="https://yastatic.net/bem-components/2.3.0/desktop/bem-components.js+bemhtml.js"></script>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="appController as vm">
    <ng-bem ng-cloak="">
      [
          {
              block : 'menu',
              mods : {
                  theme : 'islands',
                  mode: 'radio',
                  size : 'xl'
              },
              val:'qew',
              attrs : {
                  'ng-model' : 'vm.menuVal',
                  'ng-change' : 'vm.log("menu changed")'
              },
              content:  [{
                  block : 'menu-item',
                  attrs : {
                    'ng-repeat': 'item in vm.items'
                  },
                  val : '{{item}}',
                  content : '{{item}}'
              }]
          },
          {
              block : 'input',
              mods : {
                  theme : 'islands',
                  size : 'xl',
                  angular : true
              },
              attrs : {
                  'ng-model' : 'vm.hello',
                  'ng-change' : 'vm.log("input changed")'
              }
          },
          {
              block : 'button',
              mods : {
                  theme : 'islands',
                  size : 'xl'
              },
              text: 'Prepend',
              attrs : {
                  'ng-click' : 'vm.items.unshift(vm.hello); vm.hello=vm.id()'
              }
          },          {
              block : 'button',
              mods : {
                  theme : 'islands',
                  size : 'xl'
              },
              text: 'Append',
              attrs : {
                  'ng-click' : 'vm.items.push(vm.hello); vm.hello=vm.id()'
              }
          }

      ]
    </ng-bem>
    <p ng-cloak="">menuVal: {{vm.menuVal}}</p>
    <button ng-click="vm.menuVal=vm.items[3]">select 4th item</button>
    <p ng-cloak="">{{vm.hello}}</p>
    <p ng-cloak="">{{vm.llog}}</p>
  </body>

</html>
/* Put your css in here */